summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS4
-rw-r--r--Documentation/SubmitChecklist6
-rw-r--r--Documentation/feature-removal-schedule.txt19
-rw-r--r--Documentation/gpio.txt4
-rw-r--r--Documentation/kref.txt2
-rw-r--r--Documentation/mips/pci/pci.README54
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt21
-rw-r--r--Documentation/sound/alsa/Bt87x.txt4
-rw-r--r--Documentation/video4linux/CARDLIST.saa71345
-rw-r--r--Documentation/video4linux/sn9c102.txt18
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/frv/kernel/gdb-stub.c12
-rw-r--r--arch/h8300/kernel/syscalls.S78
-rw-r--r--arch/i386/Kconfig8
-rw-r--r--arch/i386/kernel/process.c1
-rw-r--r--arch/i386/kernel/smp.c2
-rw-r--r--arch/i386/kernel/syscall_table.S3
-rw-r--r--arch/i386/kernel/verify_cpu.S4
-rw-r--r--arch/i386/mm/init.c7
-rw-r--r--arch/i386/mm/pgtable.c26
-rw-r--r--arch/ia64/Kconfig4
-rw-r--r--arch/ia64/hp/common/hwsw_iommu.c2
-rw-r--r--arch/ia64/ia32/audit.c5
-rw-r--r--arch/ia64/kernel/audit.c17
-rw-r--r--arch/ia64/kernel/entry.S2
-rw-r--r--arch/ia64/kernel/err_inject.c2
-rw-r--r--arch/ia64/kernel/irq.c11
-rw-r--r--arch/ia64/kernel/kprobes.c12
-rw-r--r--arch/ia64/kernel/machvec.c2
-rw-r--r--arch/ia64/kernel/mca.c2
-rw-r--r--arch/ia64/mm/contig.c2
-rw-r--r--arch/ia64/mm/discontig.c2
-rw-r--r--arch/ia64/mm/init.c51
-rw-r--r--arch/ia64/sn/kernel/io_common.c2
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c2
-rw-r--r--arch/ia64/sn/kernel/xpnet.c4
-rw-r--r--arch/m32r/Kconfig4
-rw-r--r--arch/m32r/mm/mmu.S22
-rw-r--r--arch/mips/Kconfig212
-rw-r--r--arch/mips/Makefile42
-rw-r--r--arch/mips/au1000/Kconfig142
-rw-r--r--arch/mips/basler/excite/excite_device.c16
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/rtc.c63
-rw-r--r--arch/mips/cobalt/serial.c85
-rw-r--r--arch/mips/cobalt/setup.c31
-rw-r--r--arch/mips/configs/cobalt_defconfig49
-rw-r--r--arch/mips/configs/db1000_defconfig1
-rw-r--r--arch/mips/configs/db1100_defconfig1
-rw-r--r--arch/mips/configs/db1200_defconfig1
-rw-r--r--arch/mips/configs/db1500_defconfig1
-rw-r--r--arch/mips/configs/db1550_defconfig1
-rw-r--r--arch/mips/configs/jaguar-atx_defconfig897
-rw-r--r--arch/mips/configs/jmr3927_defconfig1
-rw-r--r--arch/mips/configs/pb1100_defconfig1
-rw-r--r--arch/mips/configs/pb1500_defconfig1
-rw-r--r--arch/mips/configs/pb1550_defconfig1
-rw-r--r--arch/mips/configs/rbhma4200_defconfig (renamed from arch/mips/configs/ocelot_g_defconfig)379
-rw-r--r--arch/mips/configs/rbhma4500_defconfig1
-rw-r--r--arch/mips/configs/tb0219_defconfig (renamed from arch/mips/configs/tb0229_defconfig)24
-rw-r--r--arch/mips/kernel/early_printk.c11
-rw-r--r--arch/mips/kernel/irq-msc01.c10
-rw-r--r--arch/mips/kernel/irq.c4
-rw-r--r--arch/mips/kernel/time.c2
-rw-r--r--arch/mips/kernel/traps.c8
-rw-r--r--arch/mips/lib/Makefile2
-rw-r--r--arch/mips/lib/ucmpdi2.c19
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c21
-rw-r--r--arch/mips/mm/highmem.c2
-rw-r--r--arch/mips/mm/init.c3
-rw-r--r--arch/mips/mm/tlbex.c36
-rw-r--r--arch/mips/momentum/Kconfig6
-rw-r--r--arch/mips/momentum/jaguar_atx/Makefile12
-rw-r--r--arch/mips/momentum/jaguar_atx/dbg_io.c125
-rw-r--r--arch/mips/momentum/jaguar_atx/irq.c94
-rw-r--r--arch/mips/momentum/jaguar_atx/ja-console.c101
-rw-r--r--arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h54
-rw-r--r--arch/mips/momentum/jaguar_atx/platform.c208
-rw-r--r--arch/mips/momentum/jaguar_atx/prom.c210
-rw-r--r--arch/mips/momentum/jaguar_atx/reset.c56
-rw-r--r--arch/mips/momentum/jaguar_atx/setup.c475
-rw-r--r--arch/mips/momentum/ocelot_g/Makefile6
-rw-r--r--arch/mips/momentum/ocelot_g/dbg_io.c121
-rw-r--r--arch/mips/momentum/ocelot_g/gt-irq.c212
-rw-r--r--arch/mips/momentum/ocelot_g/irq.c101
-rw-r--r--arch/mips/momentum/ocelot_g/ocelot_pld.h30
-rw-r--r--arch/mips/momentum/ocelot_g/prom.c84
-rw-r--r--arch/mips/momentum/ocelot_g/reset.c47
-rw-r--r--arch/mips/momentum/ocelot_g/setup.c267
-rw-r--r--arch/mips/pci/Makefile2
-rw-r--r--arch/mips/pci/fixup-cobalt.c25
-rw-r--r--arch/mips/pci/fixup-jaguar.c43
-rw-r--r--arch/mips/pci/fixup-ocelot-g.c37
-rw-r--r--arch/mips/pci/pci-ocelot-g.c97
-rw-r--r--arch/mips/sgi-ip22/Makefile2
-rw-r--r--arch/mips/sgi-ip22/ip22-platform.c177
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/boot/Makefile30
-rw-r--r--arch/powerpc/boot/cuboot-83xx.c2
-rw-r--r--arch/powerpc/boot/cuboot-85xx.c2
-rw-r--r--arch/powerpc/boot/dts/prpmc2800.dts315
-rw-r--r--arch/powerpc/boot/mpsc.c170
-rw-r--r--arch/powerpc/boot/mv64x60.c581
-rw-r--r--arch/powerpc/boot/mv64x60.h70
-rw-r--r--arch/powerpc/boot/mv64x60_i2c.c206
-rw-r--r--arch/powerpc/boot/ops.h1
-rw-r--r--arch/powerpc/boot/prpmc2800.c577
-rw-r--r--arch/powerpc/boot/serial.c2
-rw-r--r--arch/powerpc/configs/prpmc2800_defconfig1442
-rw-r--r--arch/powerpc/configs/ps3_defconfig167
-rw-r--r--arch/powerpc/kernel/audit.c17
-rw-r--r--arch/powerpc/kernel/compat_audit.c5
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/prom_parse.c2
-rw-r--r--arch/powerpc/kernel/setup-common.c41
-rw-r--r--arch/powerpc/kernel/swsusp.c4
-rw-r--r--arch/powerpc/kernel/time.c19
-rw-r--r--arch/powerpc/mm/hash_native_64.c4
-rw-r--r--arch/powerpc/platforms/cell/pervasive.c6
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig13
-rw-r--r--arch/powerpc/platforms/embedded6xx/Makefile1
-rw-r--r--arch/powerpc/platforms/embedded6xx/prpmc2800.c171
-rw-r--r--arch/powerpc/platforms/pasemi/idle.c1
-rw-r--r--arch/powerpc/platforms/ps3/setup.c2
-rw-r--r--arch/powerpc/platforms/ps3/smp.c6
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c6
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/sysdev/mv64x60.h11
-rw-r--r--arch/powerpc/sysdev/mv64x60_dev.c422
-rw-r--r--arch/powerpc/sysdev/mv64x60_pci.c172
-rw-r--r--arch/powerpc/sysdev/mv64x60_pic.c305
-rw-r--r--arch/ppc/4xx_io/serial_sicc.c10
-rw-r--r--arch/ppc/8xx_io/commproc.c2
-rw-r--r--arch/ppc/8xx_io/fec.c2
-rw-r--r--arch/ppc/boot/lib/vreset.c2
-rw-r--r--arch/ppc/boot/simple/m8xx_tty.c2
-rw-r--r--arch/ppc/boot/simple/misc-embedded.c2
-rw-r--r--arch/ppc/boot/simple/mpc52xx_tty.c2
-rw-r--r--arch/ppc/boot/simple/mv64x60_tty.c2
-rw-r--r--arch/ppc/boot/simple/rw4/stb.h2
-rw-r--r--arch/ppc/kernel/traps.c4
-rw-r--r--arch/ppc/mm/init.c2
-rw-r--r--arch/ppc/platforms/4xx/bubinga.c2
-rw-r--r--arch/ppc/platforms/4xx/ep405.c2
-rw-r--r--arch/ppc/platforms/4xx/ibmnp405h.h2
-rw-r--r--arch/ppc/platforms/4xx/sycamore.c2
-rw-r--r--arch/ppc/platforms/4xx/walnut.c2
-rw-r--r--arch/ppc/platforms/ev64360.c2
-rw-r--r--arch/ppc/platforms/hdpu.c2
-rw-r--r--arch/ppc/platforms/katana.c2
-rw-r--r--arch/ppc/platforms/mbx.h2
-rw-r--r--arch/ppc/platforms/mvme5100.h2
-rw-r--r--arch/ppc/platforms/pplus.h2
-rw-r--r--arch/ppc/platforms/prep_pci.c22
-rw-r--r--arch/ppc/platforms/prep_setup.c6
-rw-r--r--arch/ppc/platforms/prpmc750.h2
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c2
-rw-r--r--arch/ppc/platforms/sandpoint.c8
-rw-r--r--arch/ppc/syslib/harrier.c2
-rw-r--r--arch/ppc/syslib/hawk_common.c4
-rw-r--r--arch/ppc/syslib/m82xx_pci.c2
-rw-r--r--arch/ppc/syslib/mpc10x_common.c4
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c2
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c2
-rw-r--r--arch/ppc/syslib/mv64x60.c10
-rw-r--r--arch/ppc/syslib/ocp.c2
-rw-r--r--arch/ppc/syslib/ppc403_pic.c2
-rw-r--r--arch/ppc/syslib/ppc405_pci.c2
-rw-r--r--arch/ppc/syslib/ppc4xx_dma.c2
-rw-r--r--arch/ppc/syslib/ppc85xx_rio.c4
-rw-r--r--arch/ppc/syslib/xilinx_pic.c2
-rw-r--r--arch/s390/kernel/audit.c17
-rw-r--r--arch/s390/kernel/compat_audit.c5
-rw-r--r--arch/sparc/kernel/auxio.c2
-rw-r--r--arch/sparc/kernel/ioport.c2
-rw-r--r--arch/sparc/kernel/irq.c8
-rw-r--r--arch/sparc/kernel/pcic.c4
-rw-r--r--arch/sparc/kernel/process.c2
-rw-r--r--arch/sparc/kernel/sun4d_irq.c2
-rw-r--r--arch/sparc/kernel/sun4m_irq.c2
-rw-r--r--arch/sparc/kernel/systbls.S5
-rw-r--r--arch/sparc/prom/printf.c2
-rw-r--r--arch/sparc64/Kconfig3
-rw-r--r--arch/sparc64/defconfig124
-rw-r--r--arch/sparc64/kernel/audit.c17
-rw-r--r--arch/sparc64/kernel/compat_audit.c5
-rw-r--r--arch/sparc64/kernel/devices.c2
-rw-r--r--arch/sparc64/kernel/of_device.c4
-rw-r--r--arch/sparc64/kernel/pci.c4
-rw-r--r--arch/sparc64/kernel/pci_fire.c2
-rw-r--r--arch/sparc64/kernel/pci_iommu.c2
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c2
-rw-r--r--arch/sparc64/kernel/process.c2
-rw-r--r--arch/sparc64/kernel/prom.c2
-rw-r--r--arch/sparc64/kernel/systbls.S7
-rw-r--r--arch/sparc64/kernel/time.c230
-rw-r--r--arch/sparc64/mm/init.c2
-rw-r--r--arch/um/Kconfig3
-rw-r--r--arch/um/defconfig2
-rw-r--r--arch/um/include/common-offsets.h2
-rw-r--r--arch/um/include/kern_util.h3
-rw-r--r--arch/um/include/os.h1
-rw-r--r--arch/um/kernel/dyn.lds.S2
-rw-r--r--arch/um/kernel/init_task.c30
-rw-r--r--arch/um/kernel/irq.c115
-rw-r--r--arch/um/kernel/skas/process.c4
-rw-r--r--arch/um/kernel/tt/exec_kern.c2
-rw-r--r--arch/um/kernel/tt/process_kern.c2
-rw-r--r--arch/um/kernel/um_arch.c2
-rw-r--r--arch/um/kernel/uml.lds.S2
-rw-r--r--arch/um/os-Linux/signal.c50
-rw-r--r--arch/um/os-Linux/skas/process.c13
-rw-r--r--arch/um/os-Linux/sys-i386/signal.c8
-rw-r--r--arch/um/os-Linux/sys-x86_64/signal.c6
-rw-r--r--arch/um/os-Linux/util.c23
-rw-r--r--arch/x86_64/ia32/audit.c5
-rw-r--r--arch/x86_64/ia32/ia32entry.S5
-rw-r--r--arch/x86_64/kernel/aperture.c2
-rw-r--r--arch/x86_64/kernel/audit.c17
-rw-r--r--arch/x86_64/kernel/bugs.c2
-rw-r--r--arch/x86_64/kernel/head64.c7
-rw-r--r--arch/x86_64/kernel/pci-gart.c2
-rw-r--r--arch/x86_64/kernel/setup.c4
-rw-r--r--block/ll_rw_blk.c53
-rw-r--r--drivers/ata/Kconfig36
-rw-r--r--drivers/ata/Makefile2
-rw-r--r--drivers/ata/ahci.c5
-rw-r--r--drivers/ata/ata_generic.c12
-rw-r--r--drivers/ata/ata_piix.c8
-rw-r--r--drivers/ata/libata-acpi.c192
-rw-r--r--drivers/ata/libata-core.c72
-rw-r--r--drivers/ata/libata-eh.c246
-rw-r--r--drivers/ata/libata-scsi.c157
-rw-r--r--drivers/ata/libata-sff.c162
-rw-r--r--drivers/ata/libata.h7
-rw-r--r--drivers/ata/pata_ali.c36
-rw-r--r--drivers/ata/pata_amd.c13
-rw-r--r--drivers/ata/pata_artop.c25
-rw-r--r--drivers/ata/pata_atiixp.c10
-rw-r--r--drivers/ata/pata_cmd640.c11
-rw-r--r--drivers/ata/pata_cmd64x.c17
-rw-r--r--drivers/ata/pata_cs5520.c4
-rw-r--r--drivers/ata/pata_cs5530.c14
-rw-r--r--drivers/ata/pata_cs5535.c10
-rw-r--r--drivers/ata/pata_cypress.c10
-rw-r--r--drivers/ata/pata_efar.c10
-rw-r--r--drivers/ata/pata_hpt366.c17
-rw-r--r--drivers/ata/pata_hpt37x.c33
-rw-r--r--drivers/ata/pata_hpt3x2n.c13
-rw-r--r--drivers/ata/pata_hpt3x3.c10
-rw-r--r--drivers/ata/pata_it8213.c12
-rw-r--r--drivers/ata/pata_it821x.c16
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c2
-rw-r--r--drivers/ata/pata_jmicron.c10
-rw-r--r--drivers/ata/pata_marvell.c15
-rw-r--r--drivers/ata/pata_mpc52xx.c4
-rw-r--r--drivers/ata/pata_mpiix.c4
-rw-r--r--drivers/ata/pata_netcell.c10
-rw-r--r--drivers/ata/pata_ns87410.c10
-rw-r--r--drivers/ata/pata_oldpiix.c10
-rw-r--r--drivers/ata/pata_opti.c10
-rw-r--r--drivers/ata/pata_optidma.c16
-rw-r--r--drivers/ata/pata_pcmcia.c1
-rw-r--r--drivers/ata/pata_pdc202xx_old.c12
-rw-r--r--drivers/ata/pata_platform.c4
-rw-r--r--drivers/ata/pata_radisys.c10
-rw-r--r--drivers/ata/pata_rz1000.c18
-rw-r--r--drivers/ata/pata_sc1200.c12
-rw-r--r--drivers/ata/pata_scc.c4
-rw-r--r--drivers/ata/pata_serverworks.c19
-rw-r--r--drivers/ata/pata_sil680.c14
-rw-r--r--drivers/ata/pata_sis.c33
-rw-r--r--drivers/ata/pata_sl82c105.c17
-rw-r--r--drivers/ata/pata_triflex.c10
-rw-r--r--drivers/ata/pata_via.c36
-rw-r--r--drivers/ata/sata_inic162x.c4
-rw-r--r--drivers/ata/sata_nv.c16
-rw-r--r--drivers/ata/sata_sil.c4
-rw-r--r--drivers/ata/sata_sil24.c4
-rw-r--r--drivers/ata/sata_sis.c6
-rw-r--r--drivers/ata/sata_uli.c22
-rw-r--r--drivers/ata/sata_via.c6
-rw-r--r--drivers/ata/sis.h2
-rw-r--r--drivers/atm/Kconfig32
-rw-r--r--drivers/block/loop.c52
-rw-r--r--drivers/bluetooth/hci_ldisc.c10
-rw-r--r--drivers/bluetooth/hci_uart.h5
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c8
-rw-r--r--drivers/char/n_tty.c29
-rw-r--r--drivers/char/rio/riocmd.c2
-rw-r--r--drivers/char/rocket.c3
-rw-r--r--drivers/char/rocket_int.h2
-rw-r--r--drivers/char/snsc_event.c2
-rw-r--r--drivers/char/synclink_gt.c107
-rw-r--r--drivers/char/tpm/tpm_atmel.h3
-rw-r--r--drivers/char/tty_io.c77
-rw-r--r--drivers/char/watchdog/iTCO_wdt.c2
-rw-r--r--drivers/hid/hid-input.c101
-rw-r--r--drivers/hid/usbhid/Kconfig4
-rw-r--r--drivers/hid/usbhid/hid-core.c41
-rw-r--r--drivers/hid/usbhid/hid-lgff.c2
-rw-r--r--drivers/hid/usbhid/hid-plff.c2
-rw-r--r--drivers/hid/usbhid/hid-quirks.c7
-rw-r--r--drivers/hid/usbhid/hid-tmff.c2
-rw-r--r--drivers/hid/usbhid/hid-zpff.c2
-rw-r--r--drivers/hid/usbhid/hiddev.c14
-rw-r--r--drivers/hid/usbhid/usbkbd.c21
-rw-r--r--drivers/hid/usbhid/usbmouse.c9
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/media/Kconfig9
-rw-r--r--drivers/media/Makefile2
-rw-r--r--drivers/media/common/saa7146_core.c54
-rw-r--r--drivers/media/common/saa7146_fops.c1
-rw-r--r--drivers/media/dvb/Kconfig24
-rw-r--r--drivers/media/dvb/dvb-core/Kconfig14
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h5
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c565
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.h13
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c14
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c8
-rw-r--r--drivers/media/dvb/ttpci/av7110.c9
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c37
-rw-r--r--drivers/media/radio/Kconfig11
-rw-r--r--drivers/media/radio/dsbr100.c345
-rw-r--r--drivers/media/radio/radio-cadet.c297
-rw-r--r--drivers/media/radio/radio-maestro.c3
-rw-r--r--drivers/media/radio/radio-zoltrix.c1
-rw-r--r--drivers/media/video/Kconfig45
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c4
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c5
-rw-r--r--drivers/media/video/cx88/cx88-video.c1
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c7
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.h1
-rw-r--r--drivers/media/video/em28xx/Kconfig2
-rw-r--r--drivers/media/video/et61x251/Kconfig2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c2
-rw-r--r--drivers/media/video/pvrusb2/Kconfig2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c13
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c10
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c23
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c14
-rw-r--r--drivers/media/video/pwc/Kconfig2
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c123
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c17
-rw-r--r--drivers/media/video/saa7134/saa7134.h3
-rw-r--r--drivers/media/video/sn9c102/Kconfig2
-rw-r--r--drivers/media/video/sn9c102/sn9c102.h2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c91
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h4
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131d.c6
-rw-r--r--drivers/media/video/sn9c102/sn9c102_hv7131r.c8
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mi0343.c51
-rw-r--r--drivers/media/video/sn9c102/sn9c102_mi0360.c220
-rw-r--r--drivers/media/video/sn9c102/sn9c102_ov7630.c25
-rw-r--r--drivers/media/video/sn9c102/sn9c102_ov7660.c63
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas106b.c14
-rw-r--r--drivers/media/video/sn9c102/sn9c102_pas202bcb.c48
-rw-r--r--drivers/media/video/sn9c102/sn9c102_sensor.h33
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5110c1b.c2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5110d.c2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_tas5130d1b.c2
-rw-r--r--drivers/media/video/usbvideo/Kconfig8
-rw-r--r--drivers/media/video/usbvision/Kconfig2
-rw-r--r--drivers/media/video/v4l1-compat.c62
-rw-r--r--drivers/media/video/video-buf.c4
-rw-r--r--drivers/media/video/videodev.c50
-rw-r--r--drivers/media/video/zc0301/Kconfig2
-rw-r--r--drivers/net/Kconfig18
-rw-r--r--drivers/net/irda/Kconfig14
-rw-r--r--drivers/net/irda/Makefile1
-rw-r--r--drivers/net/irda/kingsun-sir.c657
-rw-r--r--drivers/net/mlx4/eq.c2
-rw-r--r--drivers/net/netxen/netxen_nic_main.c2
-rw-r--r--drivers/net/pcmcia/Kconfig23
-rw-r--r--drivers/net/phy/Kconfig22
-rw-r--r--drivers/net/phy/davicom.c34
-rw-r--r--drivers/net/s2io.c368
-rw-r--r--drivers/net/s2io.h32
-rw-r--r--drivers/net/sgiseeq.c83
-rw-r--r--drivers/net/skge.c9
-rw-r--r--drivers/net/sky2.c53
-rw-r--r--drivers/net/spider_net.c8
-rw-r--r--drivers/net/wan/Kconfig34
-rw-r--r--drivers/net/wireless/libertas/Makefile9
-rw-r--r--drivers/net/wireless/libertas/README516
-rw-r--r--drivers/net/wireless/libertas/assoc.c41
-rw-r--r--drivers/net/wireless/libertas/cmd.c23
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c4
-rw-r--r--drivers/net/wireless/libertas/debugfs.c31
-rw-r--r--drivers/net/wireless/libertas/defs.h52
-rw-r--r--drivers/net/wireless/libertas/dev.h14
-rw-r--r--drivers/net/wireless/libertas/fw.c9
-rw-r--r--drivers/net/wireless/libertas/if_usb.c5
-rw-r--r--drivers/net/wireless/libertas/if_usb.h2
-rw-r--r--drivers/net/wireless/libertas/ioctl.c1529
-rw-r--r--drivers/net/wireless/libertas/join.c194
-rw-r--r--drivers/net/wireless/libertas/join.h7
-rw-r--r--drivers/net/wireless/libertas/main.c7
-rw-r--r--drivers/net/wireless/libertas/rx.c4
-rw-r--r--drivers/net/wireless/libertas/scan.c203
-rw-r--r--drivers/net/wireless/libertas/scan.h22
-rw-r--r--drivers/net/wireless/libertas/tx.c2
-rw-r--r--drivers/net/wireless/libertas/version.h7
-rw-r--r--drivers/net/wireless/libertas/wext.c448
-rw-r--r--drivers/net/wireless/libertas/wext.h85
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c36
-rw-r--r--drivers/pci/msi.c6
-rw-r--r--drivers/pci/quirks.c1
-rw-r--r--drivers/rtc/Kconfig4
-rw-r--r--drivers/rtc/rtc-rs5c313.c28
-rw-r--r--drivers/sbus/char/envctrl.c1
-rw-r--r--drivers/scsi/sgiwd93.c264
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c654
-rw-r--r--drivers/video/Kconfig34
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/atmel_lcdfb.c752
-rw-r--r--drivers/video/console/Kconfig7
-rw-r--r--drivers/video/nvidia/nv_hw.c4
-rw-r--r--drivers/video/nvidia/nvidia.c1
-rw-r--r--drivers/video/pm2fb.c38
-rw-r--r--drivers/video/pm3fb.c3983
-rw-r--r--drivers/video/riva/rivafb-i2c.c2
-rw-r--r--fs/Makefile4
-rw-r--r--fs/afs/afs.h23
-rw-r--r--fs/afs/afs_fs.h3
-rw-r--r--fs/afs/dir.c18
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/afs/fsclient.c298
-rw-r--r--fs/afs/inode.c10
-rw-r--r--fs/afs/internal.h6
-rw-r--r--fs/afs/super.c44
-rw-r--r--fs/afs/vnode.c85
-rw-r--r--fs/afs/write.c5
-rw-r--r--fs/aio.c28
-rw-r--r--fs/anon_inodes.c200
-rw-r--r--fs/autofs/autofs_i.h4
-rw-r--r--fs/autofs/inode.c47
-rw-r--r--fs/autofs/root.c83
-rw-r--r--fs/autofs4/inode.c16
-rw-r--r--fs/autofs4/root.c18
-rw-r--r--fs/compat.c49
-rw-r--r--fs/eventfd.c228
-rw-r--r--fs/eventpoll.c1178
-rw-r--r--fs/exec.c15
-rw-r--r--fs/mpage.c174
-rw-r--r--fs/namei.c2
-rw-r--r--fs/ntfs/aops.c36
-rw-r--r--fs/ntfs/file.c59
-rw-r--r--fs/partitions/Kconfig2
-rw-r--r--fs/partitions/efi.c12
-rw-r--r--fs/signalfd.c349
-rw-r--r--fs/timerfd.c227
-rw-r--r--fs/xattr.c2
-rw-r--r--include/asm-alpha/poll.h26
-rw-r--r--include/asm-arm/poll.h28
-rw-r--r--include/asm-arm26/poll.h22
-rw-r--r--include/asm-avr32/poll.h28
-rw-r--r--include/asm-cris/poll.h27
-rw-r--r--include/asm-frv/poll.h18
-rw-r--r--include/asm-generic/Kbuild1
-rw-r--r--include/asm-generic/audit_signal.h3
-rw-r--r--include/asm-generic/poll.h37
-rw-r--r--include/asm-h8300/poll.h18
-rw-r--r--include/asm-h8300/unistd.h66
-rw-r--r--include/asm-i386/alternative.h6
-rw-r--r--include/asm-i386/pgalloc.h2
-rw-r--r--include/asm-i386/pgtable.h5
-rw-r--r--include/asm-i386/poll.h28
-rw-r--r--include/asm-i386/tsc.h6
-rw-r--r--include/asm-i386/unistd.h5
-rw-r--r--include/asm-ia64/irq.h6
-rw-r--r--include/asm-ia64/kprobes.h4
-rw-r--r--include/asm-ia64/pgalloc.h82
-rw-r--r--include/asm-ia64/poll.h33
-rw-r--r--include/asm-ia64/unistd.h4
-rw-r--r--include/asm-m32r/pgtable-2level.h4
-rw-r--r--include/asm-m32r/pgtable.h2
-rw-r--r--include/asm-m32r/poll.h33
-rw-r--r--include/asm-m32r/system.h11
-rw-r--r--include/asm-m68k/atarihw.h2
-rw-r--r--include/asm-m68k/atariints.h2
-rw-r--r--include/asm-m68k/poll.h17
-rw-r--r--include/asm-mips/atomic.h2
-rw-r--r--include/asm-mips/bootinfo.h4
-rw-r--r--include/asm-mips/fpu.h23
-rw-r--r--include/asm-mips/hazards.h32
-rw-r--r--include/asm-mips/highmem.h42
-rw-r--r--include/asm-mips/mach-cobalt/cobalt.h2
-rw-r--r--include/asm-mips/mach-ja/cpu-feature-overrides.h45
-rw-r--r--include/asm-mips/mach-ja/spaces.h20
-rw-r--r--include/asm-mips/mips-boards/malta.h4
-rw-r--r--include/asm-mips/msc01_ic.h5
-rw-r--r--include/asm-mips/page.h4
-rw-r--r--include/asm-mips/poll.h21
-rw-r--r--include/asm-mips/serial.h41
-rw-r--r--include/asm-mips/sgi/seeq.h21
-rw-r--r--include/asm-mips/sgi/wd.h20
-rw-r--r--include/asm-mips/system.h5
-rw-r--r--include/asm-parisc/poll.h28
-rw-r--r--include/asm-powerpc/hw_irq.h11
-rw-r--r--include/asm-powerpc/poll.h25
-rw-r--r--include/asm-s390/poll.h36
-rw-r--r--include/asm-sh/poll.h28
-rw-r--r--include/asm-sh64/poll.h33
-rw-r--r--include/asm-sparc/poll.h14
-rw-r--r--include/asm-sparc/unistd.h5
-rw-r--r--include/asm-sparc64/poll.h14
-rw-r--r--include/asm-sparc64/unistd.h5
-rw-r--r--include/asm-um/thread_info.h2
-rw-r--r--include/asm-v850/poll.h17
-rw-r--r--include/asm-x86_64/alternative.h6
-rw-r--r--include/asm-x86_64/page.h9
-rw-r--r--include/asm-x86_64/poll.h28
-rw-r--r--include/asm-x86_64/unistd.h9
-rw-r--r--include/asm-xtensa/poll.h20
-rw-r--r--include/linux/Kbuild3
-rw-r--r--include/linux/aio.h6
-rw-r--r--include/linux/aio_abi.h18
-rw-r--r--include/linux/anon_inodes.h16
-rw-r--r--include/linux/audit.h21
-rw-r--r--include/linux/compat.h5
-rw-r--r--include/linux/eventfd.h29
-rw-r--r--include/linux/genhd.h6
-rw-r--r--include/linux/hid.h1
-rw-r--r--include/linux/i2c-id.h1
-rw-r--r--include/linux/init_task.h32
-rw-r--r--include/linux/interrupt.h10
-rw-r--r--include/linux/kernel.h15
-rw-r--r--include/linux/libata.h31
-rw-r--r--include/linux/list.h8
-rw-r--r--include/linux/magic.h1
-rw-r--r--include/linux/module.h2
-rw-r--r--include/linux/mpage.h1
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/netfilter/x_tables.h8
-rw-r--r--include/linux/netfilter_arp/arp_tables.h41
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h22
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h22
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/pid.h5
-rw-r--r--include/linux/sched.h6
-rw-r--r--include/linux/signal.h1
-rw-r--r--include/linux/signalfd.h97
-rw-r--r--include/linux/synclink.h24
-rw-r--r--include/linux/syscalls.h4
-rw-r--r--include/linux/task_io_accounting_ops.h28
-rw-r--r--include/linux/timerfd.h17
-rw-r--r--include/linux/tty_driver.h9
-rw-r--r--include/linux/tty_ldisc.h7
-rw-r--r--include/linux/writeback.h10
-rw-r--r--include/media/saa7146.h2
-rw-r--r--include/media/saa7146_vv.h2
-rw-r--r--include/net/netfilter/nf_conntrack.h7
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h3
-rw-r--r--include/net/netfilter/nf_nat_rule.h11
-rw-r--r--include/net/udp.h9
-rw-r--r--include/net/udplite.h2
-rw-r--r--include/sound/ak4114.h4
-rw-r--r--include/sound/mpu401.h1
-rw-r--r--include/sound/pcm.h7
-rw-r--r--include/sound/version.h4
-rw-r--r--include/video/atmel_lcdc.h196
-rw-r--r--include/video/pm3fb.h110
-rw-r--r--init/Kconfig40
-rw-r--r--init/main.c1
-rw-r--r--ipc/mqueue.c4
-rw-r--r--kernel/audit.h13
-rw-r--r--kernel/auditfilter.c48
-rw-r--r--kernel/auditsc.c311
-rw-r--r--kernel/compat.c8
-rw-r--r--kernel/exit.c22
-rw-r--r--kernel/fork.c24
-rw-r--r--kernel/irq/proc.c7
-rw-r--r--kernel/pid.c11
-rw-r--r--kernel/ptrace.c3
-rw-r--r--kernel/signal.c32
-rw-r--r--kernel/stop_machine.c4
-rw-r--r--kernel/sys.c14
-rw-r--r--kernel/sys_ni.c7
-rw-r--r--lib/Kconfig.debug1
-rw-r--r--lib/Makefile2
-rw-r--r--lib/audit.c11
-rw-r--r--lib/hexdump.c104
-rw-r--r--mm/page-writeback.c59
-rw-r--r--mm/thrash.c5
-rw-r--r--mm/vmstat.c2
-rw-r--r--net/bluetooth/hidp/core.c14
-rw-r--r--net/core/link_watch.c166
-rw-r--r--net/ipv4/netfilter/arptable_filter.c140
-rw-r--r--net/ipv4/netfilter/iptable_filter.c73
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c99
-rw-r--r--net/ipv4/netfilter/iptable_raw.c79
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c86
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c11
-rw-r--r--net/ipv4/udp.c85
-rw-r--r--net/ipv4/udp_impl.h6
-rw-r--r--net/ipv4/udplite.c7
-rw-r--r--net/ipv6/addrconf.c4
-rw-r--r--net/ipv6/exthdrs.c16
-rw-r--r--net/ipv6/ip6_output.c13
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c70
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c96
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c52
-rw-r--r--net/ipv6/udp.c21
-rw-r--r--net/ipv6/udp_impl.h2
-rw-r--r--net/ipv6/udplite.c2
-rw-r--r--net/mac80211/ieee80211_sta.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c14
-rw-r--r--net/netfilter/nf_conntrack_netlink.c40
-rw-r--r--net/netfilter/xt_conntrack.c54
-rw-r--r--net/sched/sch_generic.c41
-rw-r--r--net/sched/sch_teql.c5
-rw-r--r--net/sctp/socket.c19
-rw-r--r--net/sctp/ulpevent.c11
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.c4
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c4
-rw-r--r--sound/aoa/soundbus/core.c2
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-core.c5
-rw-r--r--sound/aoa/soundbus/soundbus.h2
-rw-r--r--sound/core/pcm_native.c30
-rw-r--r--sound/core/rtctimer.c3
-rw-r--r--sound/drivers/mpu401/mpu401.c12
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c18
-rw-r--r--sound/drivers/mts64.c4
-rw-r--r--sound/drivers/portman2x4.c4
-rw-r--r--sound/drivers/vx/vx_hwdep.c14
-rw-r--r--sound/i2c/other/ak4114.c114
-rw-r--r--sound/isa/Kconfig22
-rw-r--r--sound/isa/ad1816a/ad1816a.c8
-rw-r--r--sound/isa/ad1848/ad1848.c167
-rw-r--r--sound/isa/adlib.c122
-rw-r--r--sound/isa/cmi8330.c115
-rw-r--r--sound/isa/cs423x/cs4231.c213
-rw-r--r--sound/isa/cs423x/cs4231_lib.c4
-rw-r--r--sound/isa/cs423x/cs4236.c131
-rw-r--r--sound/isa/es1688/es1688.c251
-rw-r--r--sound/isa/es18xx.c110
-rw-r--r--sound/isa/gus/gusclassic.c292
-rw-r--r--sound/isa/gus/gusextreme.c379
-rw-r--r--sound/isa/gus/gusmax.c71
-rw-r--r--sound/isa/gus/interwave.c101
-rw-r--r--sound/isa/opl3sa2.c127
-rw-r--r--sound/isa/opti9xx/miro.c80
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c108
-rw-r--r--sound/isa/sb/sb16.c113
-rw-r--r--sound/isa/sb/sb16_csp.c30
-rw-r--r--sound/isa/sb/sb8.c90
-rw-r--r--sound/isa/sgalaxy.c107
-rw-r--r--sound/isa/sscape.c120
-rw-r--r--sound/isa/wavefront/wavefront.c113
-rw-r--r--sound/isa/wavefront/wavefront_fx.c23
-rw-r--r--sound/pci/Kconfig33
-rw-r--r--sound/pci/ac97/Makefile2
-rw-r--r--sound/pci/ac97/ac97_codec.c43
-rw-r--r--sound/pci/ac97/ac97_local.h55
-rw-r--r--sound/pci/ac97/ac97_patch.c194
-rw-r--r--sound/pci/ac97/ac97_patch.h110
-rw-r--r--sound/pci/ac97/ac97_pcm.c1
-rw-r--r--sound/pci/ali5451/ali5451.c869
-rw-r--r--sound/pci/au88x0/au88x0_sb.h40
-rw-r--r--sound/pci/azt3328.c34
-rw-r--r--sound/pci/azt3328.h4
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c2
-rw-r--r--sound/pci/cs46xx/imgs/cwcemb80.h1607
-rw-r--r--sound/pci/echoaudio/darla20.c2
-rw-r--r--sound/pci/echoaudio/darla24.c2
-rw-r--r--sound/pci/echoaudio/echo3g.c4
-rw-r--r--sound/pci/echoaudio/echoaudio.c4
-rw-r--r--sound/pci/echoaudio/echoaudio_3g.c4
-rw-r--r--sound/pci/echoaudio/gina20.c2
-rw-r--r--sound/pci/echoaudio/gina24.c6
-rw-r--r--sound/pci/echoaudio/indigo.c3
-rw-r--r--sound/pci/echoaudio/indigodj.c3
-rw-r--r--sound/pci/echoaudio/indigoio.c3
-rw-r--r--sound/pci/echoaudio/layla20.c3
-rw-r--r--sound/pci/echoaudio/layla24.c6
-rw-r--r--sound/pci/echoaudio/mia.c3
-rw-r--r--sound/pci/echoaudio/mona.c9
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c24
-rw-r--r--sound/pci/emu10k1/p16v.c4
-rw-r--r--sound/pci/ens1370.c8
-rw-r--r--sound/pci/es1968.c11
-rw-r--r--sound/pci/hda/Makefile9
-rw-r--r--sound/pci/hda/hda_codec.c729
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_generic.c2
-rw-r--r--sound/pci/hda/hda_intel.c31
-rw-r--r--sound/pci/hda/hda_local.h12
-rw-r--r--sound/pci/hda/patch_analog.c85
-rw-r--r--sound/pci/hda/patch_atihdmi.c17
-rw-r--r--sound/pci/hda/patch_cmedia.c14
-rw-r--r--sound/pci/hda/patch_conexant.c310
-rw-r--r--sound/pci/hda/patch_realtek.c2269
-rw-r--r--sound/pci/hda/patch_sigmatel.c178
-rw-r--r--sound/pci/hda/patch_via.c14
-rw-r--r--sound/pci/ice1712/amp.c2
-rw-r--r--sound/pci/ice1712/amp.h2
-rw-r--r--sound/pci/ice1712/aureon.c18
-rw-r--r--sound/pci/ice1712/aureon.h2
-rw-r--r--sound/pci/ice1712/delta.c34
-rw-r--r--sound/pci/ice1712/delta.h2
-rw-r--r--sound/pci/ice1712/ews.c24
-rw-r--r--sound/pci/ice1712/ews.h2
-rw-r--r--sound/pci/ice1712/hoontech.c6
-rw-r--r--sound/pci/ice1712/hoontech.h2
-rw-r--r--sound/pci/ice1712/ice1712.c50
-rw-r--r--sound/pci/ice1712/ice1712.h3
-rw-r--r--sound/pci/ice1712/ice1724.c47
-rw-r--r--sound/pci/ice1712/juli.c24
-rw-r--r--sound/pci/ice1712/juli.h2
-rw-r--r--sound/pci/ice1712/phase.c14
-rw-r--r--sound/pci/ice1712/phase.h2
-rw-r--r--sound/pci/ice1712/pontis.c6
-rw-r--r--sound/pci/ice1712/pontis.h2
-rw-r--r--sound/pci/ice1712/prodigy192.c360
-rw-r--r--sound/pci/ice1712/prodigy192.h10
-rw-r--r--sound/pci/ice1712/revo.c26
-rw-r--r--sound/pci/ice1712/revo.h2
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c6
-rw-r--r--sound/pci/ice1712/vt1720_mobo.h2
-rw-r--r--sound/pci/ice1712/wtm.c2
-rw-r--r--sound/pci/intel8x0.c20
-rw-r--r--sound/pci/korg1212/korg1212.c25
-rw-r--r--sound/pci/maestro3.c38
-rw-r--r--sound/pci/mixart/mixart_hwdep.c3
-rw-r--r--sound/pci/pcxhr/pcxhr.c28
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c6
-rw-r--r--sound/pci/riptide/riptide.c1
-rw-r--r--sound/pci/rme32.c7
-rw-r--r--sound/pci/rme9652/hdsp.c99
-rw-r--r--sound/pci/rme9652/hdspm.c185
-rw-r--r--sound/pci/rme9652/rme9652.c8
-rw-r--r--sound/pci/trident/trident_main.c4
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c55
-rw-r--r--sound/pcmcia/vx/vxpocket.c2
-rw-r--r--sound/soc/Kconfig18
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/at91/Kconfig10
-rw-r--r--sound/soc/at91/Makefile4
-rw-r--r--sound/soc/at91/at91-ssc.c (renamed from sound/soc/at91/at91-i2s.c)259
-rw-r--r--sound/soc/at91/at91-ssc.h (renamed from sound/soc/at91/at91-i2s.h)14
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c8
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ac97.c1
-rw-r--r--sound/soc/codecs/ac97.h1
-rw-r--r--sound/soc/codecs/wm8750.c2
-rw-r--r--sound/soc/codecs/wm8753.c1811
-rw-r--r--sound/soc/codecs/wm8753.h126
-rw-r--r--sound/soc/codecs/wm9712.c7
-rw-r--r--sound/soc/pxa/Kconfig4
-rw-r--r--sound/soc/s3c24xx/Kconfig10
-rw-r--r--sound/soc/s3c24xx/Makefile6
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c441
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.h37
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c468
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.h31
-rw-r--r--sound/soc/soc-dapm.c6
-rw-r--r--sound/sparc/cs4231.c4
-rw-r--r--sound/usb/Kconfig28
-rw-r--r--sound/usb/Makefile2
-rw-r--r--sound/usb/caiaq/Makefile3
-rw-r--r--sound/usb/caiaq/caiaq-audio.c707
-rw-r--r--sound/usb/caiaq/caiaq-audio.h7
-rw-r--r--sound/usb/caiaq/caiaq-device.c436
-rw-r--r--sound/usb/caiaq/caiaq-device.h116
-rw-r--r--sound/usb/caiaq/caiaq-input.c246
-rw-r--r--sound/usb/caiaq/caiaq-input.h8
-rw-r--r--sound/usb/caiaq/caiaq-midi.c177
-rw-r--r--sound/usb/caiaq/caiaq-midi.h8
-rw-r--r--sound/usb/usbaudio.c3
-rw-r--r--sound/usb/usbmidi.c58
-rw-r--r--sound/usb/usbquirks.h23
783 files changed, 27532 insertions, 21432 deletions
diff --git a/CREDITS b/CREDITS
index 6829e91a88d..273d72b610c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2299,8 +2299,8 @@ E: acme@redhat.com
W: http://oops.ghostprotocols.net:81/blog/
P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01
D: IPX, LLC, DCCP, cyc2x, wl3501_cs, net/ hacks
-S: R. Brasílio Itiberê, 4270/1010 - Água Verde
-S: 80240-060 - Curitiba - Paraná
+S: R. Brasílio Itiberê, 4270/1010 - Ãgua Verde
+S: 80240-060 - Curitiba - Paraná
S: Brazil
N: Karsten Merker
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index 6491b2c45dd..3af3e65cf43 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -73,9 +73,9 @@ kernel patches.
If the new code is substantial, addition of subsystem-specific fault
injection might be appropriate.
-22: Newly-added code has been compiled with `gcc -W'. This will generate
- lots of noise, but is good for finding bugs like "warning: comparison
- between signed and unsigned".
+22: Newly-added code has been compiled with `gcc -W' (use "make
+ EXTRA_CFLAGS=-W"). This will generate lots of noise, but is good for
+ finding bugs like "warning: comparison between signed and unsigned".
23: Tested after it has been merged into the -mm patchset to make sure
that it still works with all of the other queued patches and various
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c6322c76034..498ff31f3aa 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -328,3 +328,22 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
+What: libata.spindown_compat module parameter
+When: Dec 2008
+Why: halt(8) synchronizes caches for and spins down libata disks
+ because libata didn't use to spin down disk on system halt
+ (only synchronized caches).
+ Spin down on system halt is now implemented and can be tested
+ using sysfs node /sys/class/scsi_disk/h:c:i:l/manage_start_stop.
+ Because issuing spin down command to an already spun down disk
+ makes some disks spin up just to spin down again, the old
+ behavior needs to be maintained till userspace tool is updated
+ to check the sysfs node and not to spin down disks with the
+ node set to one.
+ This module parameter is to give userspace tool the time to
+ get updated and should be removed after userspace is
+ reasonably updated.
+Who: Tejun Heo <htejun@gmail.com>
+
+---------------------------
+
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index f8528db967f..e8be0abb346 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -66,7 +66,9 @@ registers; another might implement it by delegating through abstractions
used for several very different kinds of GPIO controller.
That said, if the convention is supported on their platform, drivers should
-use it when possible:
+use it when possible. Platforms should declare GENERIC_GPIO support in
+Kconfig (boolean true), which multi-platform drivers can depend on when
+using the include file:
#include <asm/gpio.h>
diff --git a/Documentation/kref.txt b/Documentation/kref.txt
index 42fe2844591..f38b59d00c6 100644
--- a/Documentation/kref.txt
+++ b/Documentation/kref.txt
@@ -67,7 +67,7 @@ void more_data_handling(void *cb_data)
.
. do stuff with data here
.
- kref_put(data, data_release);
+ kref_put(&data->refcount, data_release);
}
int my_data_handler(void)
diff --git a/Documentation/mips/pci/pci.README b/Documentation/mips/pci/pci.README
deleted file mode 100644
index 8697ee41372..00000000000
--- a/Documentation/mips/pci/pci.README
+++ /dev/null
@@ -1,54 +0,0 @@
-
-Pete Popov, ppopov@pacbell.net
-07/11/2001
-
-This README briefly explains how to use the pci and pci_auto
-code in arch/mips/kernel. The code was ported from PowerPC and
-modified slightly. It has been tested pretty well on PPC on some
-rather complex systems with multiple bridges and devices behind
-each bridge. However, at the time this README was written, the
-mips port was tested only on boards with a single pci bus and
-no P2P bridges. It's very possible that on boards with P2P
-bridges some modifications have to be made. The code will
-evolve, no doubt, but currently every single mips board
-is doing its own pcibios thing and it has become a big
-mess. This generic pci code is meant to clean up the mips
-pci mess and make it easier to add pci support to new boards.
-
-inside the define for your board in arch/mips/config.in.
-For example, the Galileo EV96100 board looks like this:
-
-if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
- define_bool CONFIG_PCI y
- define_bool CONFIG_MIPS_GT96100 y
- define_bool CONFIG_NEW_PCI y
- define_bool CONFIG_SWAP_IO_SPACE y
-fi
-
-
-Next, if you want to use the arch/mips/kernel/pci code, which has the
-pcibios_init() function, add
-
-define_bool CONFIG_NEW_PCI y
-
-inside the define for your board. Again, the EV96100 example above
-show NEW_PCI turned on.
-
-
-Now you need to add your files to hook in your pci configuration
-cycles. Usually you'll need only a couple of files named something
-like pci_fixups.c and pci_ops.c. You can copy the templates
-provided and fill in the code.
-
-The file pci_ops.c should contain the pci configuration cycles routines.
-It also has the mips_pci_channels[] array which contains the descriptors
-of each pci controller.
-
-The file pci_fixups.c contains a few routines to do interrupt fixups,
-resources fixups, and, if needed, pci bios fixups.
-
-Usually you'll put your pci_fixups.c file in your board specific directory,
-since the functions in that file are board specific. The functions in
-pci_ops.c, on the other hand, are usually pci controller specific so that
-file could be shared among a few different boards using the same
-pci controller.
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 73e9a174b64..57b878cc393 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -821,6 +821,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
6stack-dig 6-jack digital with SPDIF I/O
arima Arima W820Di1
macpro MacPro support
+ w2jc ASUS W2JC
auto auto-config reading BIOS (default)
ALC883/888
@@ -852,6 +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)
+ lenovo Lenovo 3000 C200
auto auto-config reading BIOS (default)
CMI9880
@@ -909,6 +911,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
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
@@ -924,6 +927,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
vaio Setup for VAIO FE550G/SZ110
vaio-ar Setup for VAIO AR
+ The model name "genric" is treated as a special case. When this
+ model is given, the driver uses the generic codec parser without
+ "codec-patch". It's sometimes good for testing and debugging.
+
If the default configuration doesn't work and one of the above
matches with your device, report it together with the PCI
subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
@@ -1278,6 +1285,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
port - port number or -1 (disable)
irq - IRQ number or -1 (disable)
pnp - PnP detection - 0 = disable, 1 = enable (default)
+ uart_enter - Issue UART_ENTER command at open - bool, default = on
This module supports multiple devices and PnP.
@@ -1692,6 +1700,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple devices, autoprobe and hotplugging.
+ Module snd-usb-caiaq
+ --------------------
+
+ Module for caiaq UB audio interfaces,
+ * Native Instruments RigKontrol2
+ * Native Instruments Kore Controller
+ * Native Instruments Audio Kontrol 1
+ * Native Instruments Audio 8 DJ
+
+ This module supports multiple devices, autoprobe and hotplugging.
+
Module snd-usb-usx2y
--------------------
@@ -2046,4 +2065,4 @@ Links and Addresses
https://bugtrack.alsa-project.org/bugs/
ALSA Developers ML
- mailto:alsa-devel@lists.sourceforge.net
+ mailto:alsa-devel@alsa-project.org
diff --git a/Documentation/sound/alsa/Bt87x.txt b/Documentation/sound/alsa/Bt87x.txt
index 11edb2fd2a5..f158cde8b06 100644
--- a/Documentation/sound/alsa/Bt87x.txt
+++ b/Documentation/sound/alsa/Bt87x.txt
@@ -36,8 +36,8 @@ recorded data is not right, try to specify the digital_rate option with
other values than the default 32000 (often it's 44100 or 64000).
If you have an unknown card, please mail the ID and board name to
-<alsa-devel@lists.sf.net>, regardless of whether audio capture works or
-not, so that future versions of this driver know about your card.
+<alsa-devel@alsa-project.org>, regardless of whether audio capture works
+or not, so that future versions of this driver know about your card.
Audio modes
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index d7bb2e2e4d9..712e8c8333c 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -52,7 +52,7 @@
51 -> ProVideo PV952 [1540:9524]
52 -> AverMedia AverTV/305 [1461:2108]
53 -> ASUS TV-FM 7135 [1043:4845]
- 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,1489:0214,5168:0304]
+ 54 -> LifeView FlyTV Platinum FM / Gold [5168:0214,5168:5214,1489:0214,5168:0304]
55 -> LifeView FlyDVB-T DUO / MSI TV@nywhere Duo [5168:0306,4E42:0306]
56 -> Avermedia AVerTV 307 [1461:a70a]
57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
@@ -111,3 +111,6 @@
110 -> Avermedia M102 [1461:f31e]
111 -> ASUS P7131 4871 [1043:4871]
112 -> ASUSTeK P7131 Hybrid [1043:4876]
+113 -> Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) [1019:4cb6]
+114 -> KWorld DVB-T 210 [17de:7250]
+115 -> Sabrent PCMCIA TV-PCB05 [0919:2003]
diff --git a/Documentation/video4linux/sn9c102.txt b/Documentation/video4linux/sn9c102.txt
index 5fe0ad7dfc2..279717c96f6 100644
--- a/Documentation/video4linux/sn9c102.txt
+++ b/Documentation/video4linux/sn9c102.txt
@@ -355,6 +355,9 @@ devices assembling the SN9C1xx PC camera controllers:
Vendor ID Product ID
--------- ----------
+0x0458 0x7025
+0x045e 0x00f5
+0x045e 0x00f7
0x0471 0x0327
0x0471 0x0328
0x0c45 0x6001
@@ -432,7 +435,7 @@ Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
HV7131D Hynix Semiconductor | Yes No No No
HV7131R Hynix Semiconductor | No Yes Yes Yes
MI-0343 Micron Technology | Yes No No No
-MI-0360 Micron Technology | No Yes No No
+MI-0360 Micron Technology | No Yes Yes Yes
OV7630 OmniVision Technologies | Yes Yes No No
OV7660 OmniVision Technologies | No No Yes Yes
PAS106B PixArt Imaging | Yes No No No
@@ -478,13 +481,12 @@ scaling factor is restored to 1.
This driver supports two different video formats: the first one is the "8-bit
Sequential Bayer" format and can be used to obtain uncompressed video data
from the device through the current I/O method, while the second one provides
-"raw" compressed video data (without frame headers not related to the
-compressed data). The compression quality may vary from 0 to 1 and can be
-selected or queried thanks to the VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2
-ioctl's. For maximum flexibility, both the default active video format and the
-default compression quality depend on how the image sensor being used is
-initialized (as described in the documentation of the API for the image sensors
-supplied by this driver).
+either "raw" compressed video data (without frame headers not related to the
+compressed data) or standard JPEG (with frame headers). The compression quality
+may vary from 0 to 1 and can be selected or queried thanks to the
+VIDIOC_S_JPEGCOMP and VIDIOC_G_JPEGCOMP V4L2 ioctl's. For maximum flexibility,
+both the default active video format and the default compression quality
+depend on how the image sensor being used is initialized.
11. Video frame formats [1]
diff --git a/MAINTAINERS b/MAINTAINERS
index bd558ac5bb7..68a56add73e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -372,7 +372,7 @@ AOA (Apple Onboard Audio) ALSA DRIVER
P: Johannes Berg
M: johannes@sipsolutions.net
L: linuxppc-dev@ozlabs.org
-L: alsa-devel@alsa-project.org
+L: alsa-devel@alsa-project.org (subscribers-only)
S: Maintained
APM DRIVER
@@ -3239,13 +3239,13 @@ S: Maintained
SOUND
P: Jaroslav Kysela
M: perex@suse.cz
-L: alsa-devel@alsa-project.org
+L: alsa-devel@alsa-project.org (subscribers-only)
S: Maintained
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
P: Liam Girdwood
M: liam.girdwood@wolfsonmicro.com
-L: alsa-devel@alsa-project.org
+L: alsa-devel@alsa-project.org (subscribers-only)
S: Supported
SPI SUBSYSTEM
@@ -3269,7 +3269,6 @@ W: http://tpmdd.sourceforge.net
P: Marcel Selhorst
M: tpm@selhorst.net
W: http://www.prosec.rub.de/tpm/
-L: tpmdd-devel@lists.sourceforge.net
S: Maintained
Telecom Clock Driver for MCPL0010
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
index 9550f37fb62..1e7a101cbf4 100644
--- a/arch/frv/kernel/gdb-stub.c
+++ b/arch/frv/kernel/gdb-stub.c
@@ -1195,7 +1195,7 @@ static void gdbstub_check_breakpoint(void)
/*
*
*/
-static void __attribute__((unused)) gdbstub_show_regs(void)
+static void __maybe_unused gdbstub_show_regs(void)
{
unsigned long *reg;
int loop;
@@ -1223,7 +1223,7 @@ static void __attribute__((unused)) gdbstub_show_regs(void)
/*
* dump debugging regs
*/
-static void __attribute__((unused)) gdbstub_dump_debugregs(void)
+static void __maybe_unused gdbstub_dump_debugregs(void)
{
gdbstub_printk("DCR %08lx ", __debug_status.dcr);
gdbstub_printk("BRR %08lx\n", __debug_status.brr);
@@ -2079,25 +2079,25 @@ void gdbstub_exit(int status)
* GDB wants to call malloc() and free() to allocate memory for calling kernel
* functions directly from its command line
*/
-static void *malloc(size_t size) __attribute__((unused));
+static void *malloc(size_t size) __maybe_unused;
static void *malloc(size_t size)
{
return kmalloc(size, GFP_ATOMIC);
}
-static void free(void *p) __attribute__((unused));
+static void free(void *p) __maybe_unused;
static void free(void *p)
{
kfree(p);
}
-static uint32_t ___get_HSR0(void) __attribute__((unused));
+static uint32_t ___get_HSR0(void) __maybe_unused;
static uint32_t ___get_HSR0(void)
{
return __get_HSR(0);
}
-static uint32_t ___set_HSR0(uint32_t x) __attribute__((unused));
+static uint32_t ___set_HSR0(uint32_t x) __maybe_unused;
static uint32_t ___set_HSR0(uint32_t x)
{
__set_HSR(0, x);
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
index dab98fd99e6..54e21c3f205 100644
--- a/arch/h8300/kernel/syscalls.S
+++ b/arch/h8300/kernel/syscalls.S
@@ -31,7 +31,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_mknod)
.long SYMBOL_NAME(sys_chmod) /* 15 */
.long SYMBOL_NAME(sys_chown16)
- .long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
.long SYMBOL_NAME(sys_stat)
.long SYMBOL_NAME(sys_lseek)
.long SYMBOL_NAME(sys_getpid) /* 20 */
@@ -45,11 +45,11 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_fstat)
.long SYMBOL_NAME(sys_pause)
.long SYMBOL_NAME(sys_utime) /* 30 */
- .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
- .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
.long SYMBOL_NAME(sys_access)
.long SYMBOL_NAME(sys_nice)
- .long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* 35 old ftime syscall holder */
.long SYMBOL_NAME(sys_sync)
.long SYMBOL_NAME(sys_kill)
.long SYMBOL_NAME(sys_rename)
@@ -58,7 +58,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_dup)
.long SYMBOL_NAME(sys_pipe)
.long SYMBOL_NAME(sys_times)
- .long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
.long SYMBOL_NAME(sys_brk) /* 45 */
.long SYMBOL_NAME(sys_setgid16)
.long SYMBOL_NAME(sys_getgid16)
@@ -66,13 +66,13 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_geteuid16)
.long SYMBOL_NAME(sys_getegid16) /* 50 */
.long SYMBOL_NAME(sys_acct)
- .long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
- .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
+ .long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
.long SYMBOL_NAME(sys_ioctl)
.long SYMBOL_NAME(sys_fcntl) /* 55 */
- .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
.long SYMBOL_NAME(sys_setpgid)
- .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_umask) /* 60 */
.long SYMBOL_NAME(sys_chroot)
@@ -112,7 +112,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_fchown16) /* 95 */
.long SYMBOL_NAME(sys_getpriority)
.long SYMBOL_NAME(sys_setpriority)
- .long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
.long SYMBOL_NAME(sys_statfs)
.long SYMBOL_NAME(sys_fstatfs) /* 100 */
.long SYMBOL_NAME(sys_ni_syscall) /* ioperm for i386 */
@@ -202,8 +202,8 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_capset) /* 185 */
.long SYMBOL_NAME(sys_sigaltstack)
.long SYMBOL_NAME(sys_sendfile)
- .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
- .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
+ .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
+ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
.long SYMBOL_NAME(sys_getrlimit)
.long SYMBOL_NAME(sys_mmap2)
@@ -236,10 +236,10 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_getdents64) /* 220 */
.long SYMBOL_NAME(sys_fcntl64)
- .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
- .long SYMBOL_NAME(sys_ni_syscall)
+ .long SYMBOL_NAME(sys_ni_syscall) /* reserved TUX */
+ .long SYMBOL_NAME(sys_ni_syscall) /* reserved Security */
.long SYMBOL_NAME(sys_gettid)
- .long SYMBOL_NAME(sys_ni_syscall) /* 225 */ /* sys_readahead */
+ .long SYMBOL_NAME(sys_readahead) /* 225 */
.long SYMBOL_NAME(sys_setxattr)
.long SYMBOL_NAME(sys_lsetxattr)
.long SYMBOL_NAME(sys_fsetxattr)
@@ -257,8 +257,8 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_futex) /* 240 */
.long SYMBOL_NAME(sys_sched_setaffinity)
.long SYMBOL_NAME(sys_sched_getaffinity)
- .long SYMBOL_NAME(sys_ni_syscall) /* sys_set_thread_area */
- .long SYMBOL_NAME(sys_ni_syscall) /* sys_get_thread_area */
+ .long SYMBOL_NAME(sys_ni_syscall)
+ .long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_io_setup) /* 245 */
.long SYMBOL_NAME(sys_io_destroy)
.long SYMBOL_NAME(sys_io_getevents)
@@ -288,8 +288,8 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_utimes)
.long SYMBOL_NAME(sys_fadvise64_64)
.long SYMBOL_NAME(sys_ni_syscall) /* sys_vserver */
- .long SYMBOL_NAME(sys_mbind)
- .long SYMBOL_NAME(sys_get_mempolicy)
+ .long SYMBOL_NAME(sys_ni_syscall)
+ .long SYMBOL_NAME(sys_get_mempolicy) /* 275 */
.long SYMBOL_NAME(sys_set_mempolicy)
.long SYMBOL_NAME(sys_mq_open)
.long SYMBOL_NAME(sys_mq_unlink)
@@ -297,16 +297,42 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_mq_timedreceive) /* 280 */
.long SYMBOL_NAME(sys_mq_notify)
.long SYMBOL_NAME(sys_mq_getsetattr)
- .long SYMBOL_NAME(sys_ni_syscall) /* reserved for kexec */
.long SYMBOL_NAME(sys_waitid)
- .long SYMBOL_NAME(sys_ni_syscall) /* 285 */ /* available */
- .long SYMBOL_NAME(sys_add_key)
+ .long SYMBOL_NAME(sys_ni_syscall) /* sys_kexec_load */
+ .long SYMBOL_NAME(sys_add_key) /* 285 */
.long SYMBOL_NAME(sys_request_key)
.long SYMBOL_NAME(sys_keyctl)
-
- .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
- .long SYMBOL_NAME(sys_ni_syscall)
- .endr
+ .long SYMBOL_NAME(sys_ioprio_set)
+ .long SYMBOL_NAME(sys_ioprio_get) /* 290 */
+ .long SYMBOL_NAME(sys_inotify_init)
+ .long SYMBOL_NAME(sys_inotify_add_watch)
+ .long SYMBOL_NAME(sys_inotify_rm_watch)
+ .long SYMBOL_NAME(sys_migrate_pages)
+ .long SYMBOL_NAME(sys_openat) /* 295 */
+ .long SYMBOL_NAME(sys_mkdirat)
+ .long SYMBOL_NAME(sys_mknodat)
+ .long SYMBOL_NAME(sys_fchownat)
+ .long SYMBOL_NAME(sys_futimesat)
+ .long SYMBOL_NAME(sys_fstatat64) /* 300 */
+ .long SYMBOL_NAME(sys_unlinkat)
+ .long SYMBOL_NAME(sys_renameat)
+ .long SYMBOL_NAME(sys_linkat)
+ .long SYMBOL_NAME(sys_symlinkat)
+ .long SYMBOL_NAME(sys_readlinkat) /* 305 */
+ .long SYMBOL_NAME(sys_fchmodat)
+ .long SYMBOL_NAME(sys_faccessat)
+ .long SYMBOL_NAME(sys_ni_syscall) /* sys_pselect6 */
+ .long SYMBOL_NAME(sys_ni_syscall) /* sys_ppoll */
+ .long SYMBOL_NAME(sys_unshare) /* 310 */
+ .long SYMBOL_NAME(sys_set_robust_list)
+ .long SYMBOL_NAME(sys_get_robust_list)
+ .long SYMBOL_NAME(sys_splice)
+ .long SYMBOL_NAME(sys_sync_file_range)
+ .long SYMBOL_NAME(sys_tee) /* 315 */
+ .long SYMBOL_NAME(sys_vmsplice)
+ .long SYMBOL_NAME(sys_ni_syscall) /* sys_move_pages */
+ .long SYMBOL_NAME(sys_getcpu)
+ .long SYMBOL_NAME(sys_ni_syscall) /* sys_epoll_pwait */
.macro call_sp addr
mov.l #SYMBOL_NAME(\addr),er6
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 30944ee2e61..c2d54b80223 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -55,6 +55,10 @@ config ZONE_DMA
bool
default y
+config QUICKLIST
+ bool
+ default y
+
config SBUS
bool
@@ -79,10 +83,6 @@ config ARCH_MAY_HAVE_PC_FDC
bool
default y
-config ARCH_USES_SLAB_PAGE_STRUCT
- bool
- default y
-
config DMI
bool
default y
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index d76d9bc33b3..06dfa65ad18 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -186,6 +186,7 @@ void cpu_idle(void)
if (__get_cpu_var(cpu_idle_state))
__get_cpu_var(cpu_idle_state) = 0;
+ check_pgt_cache();
rmb();
idle = pm_idle;
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 93f202a855f..706bda72dc6 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -421,7 +421,7 @@ void flush_tlb_mm (struct mm_struct * mm)
}
if (!cpus_empty(cpu_mask))
flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
-
+ check_pgt_cache();
preempt_enable();
}
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 0772678ceec..bf6adce5226 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -320,3 +320,6 @@ ENTRY(sys_call_table)
.long sys_getcpu
.long sys_epoll_pwait
.long sys_utimensat /* 320 */
+ .long sys_signalfd
+ .long sys_timerfd
+ .long sys_eventfd
diff --git a/arch/i386/kernel/verify_cpu.S b/arch/i386/kernel/verify_cpu.S
index e51a8695d54..b2a9d80b642 100644
--- a/arch/i386/kernel/verify_cpu.S
+++ b/arch/i386/kernel/verify_cpu.S
@@ -10,7 +10,9 @@ verify_cpu:
#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
pushfl
- orl $(1<<18),(%esp) # try setting AC
+ pop %eax
+ orl $(1<<18),%eax # try setting AC
+ push %eax
popfl
pushfl
popl %eax
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index c50782efa5c..b22ce8d6b1b 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -740,7 +740,6 @@ int remove_memory(u64 start, u64 size)
EXPORT_SYMBOL_GPL(remove_memory);
#endif
-struct kmem_cache *pgd_cache;
struct kmem_cache *pmd_cache;
void __init pgtable_cache_init(void)
@@ -764,12 +763,6 @@ void __init pgtable_cache_init(void)
pgd_size = PAGE_SIZE;
}
}
- pgd_cache = kmem_cache_create("pgd",
- pgd_size,
- pgd_size,
- SLAB_PANIC,
- pgd_ctor,
- (!SHARED_KERNEL_PMD) ? pgd_dtor : NULL);
}
/*
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index 9a96c164742..8d7c0864cc0 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -13,6 +13,7 @@
#include <linux/pagemap.h>
#include <linux/spinlock.h>
#include <linux/module.h>
+#include <linux/quicklist.h>
#include <asm/system.h>
#include <asm/pgtable.h>
@@ -205,8 +206,6 @@ void pmd_ctor(void *pmd, struct kmem_cache *cache, unsigned long flags)
* against pageattr.c; it is the unique case in which a valid change
* of kernel pagetables can't be lazily synchronized by vmalloc faults.
* vmalloc faults work because attached pagetables are never freed.
- * The locking scheme was chosen on the basis of manfred's
- * recommendations and having no core impact whatsoever.
* -- wli
*/
DEFINE_SPINLOCK(pgd_lock);
@@ -232,9 +231,11 @@ static inline void pgd_list_del(pgd_t *pgd)
set_page_private(next, (unsigned long)pprev);
}
+
+
#if (PTRS_PER_PMD == 1)
/* Non-PAE pgd constructor */
-void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused)
+void pgd_ctor(void *pgd)
{
unsigned long flags;
@@ -256,7 +257,7 @@ void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused)
}
#else /* PTRS_PER_PMD > 1 */
/* PAE pgd constructor */
-void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused)
+void pgd_ctor(void *pgd)
{
/* PAE, kernel PMD may be shared */
@@ -275,11 +276,12 @@ void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused)
}
#endif /* PTRS_PER_PMD */
-void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused)
+void pgd_dtor(void *pgd)
{
unsigned long flags; /* can be called from interrupt context */
- BUG_ON(SHARED_KERNEL_PMD);
+ if (SHARED_KERNEL_PMD)
+ return;
paravirt_release_pd(__pa(pgd) >> PAGE_SHIFT);
spin_lock_irqsave(&pgd_lock, flags);
@@ -321,7 +323,7 @@ static void pmd_cache_free(pmd_t *pmd, int idx)
pgd_t *pgd_alloc(struct mm_struct *mm)
{
int i;
- pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
+ pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor);
if (PTRS_PER_PMD == 1 || !pgd)
return pgd;
@@ -344,7 +346,7 @@ out_oom:
paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
pmd_cache_free(pmd, i);
}
- kmem_cache_free(pgd_cache, pgd);
+ quicklist_free(0, pgd_dtor, pgd);
return NULL;
}
@@ -361,5 +363,11 @@ void pgd_free(pgd_t *pgd)
pmd_cache_free(pmd, i);
}
/* in the non-PAE case, free_pgtables() clears user pgd entries */
- kmem_cache_free(pgd_cache, pgd);
+ quicklist_free(0, pgd_dtor, pgd);
}
+
+void check_pgt_cache(void)
+{
+ quicklist_trim(0, pgd_dtor, 25, 16);
+}
+
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 6e41471449c..de1bff65996 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -31,6 +31,10 @@ config ZONE_DMA
def_bool y
depends on !IA64_SGI_SN2
+config QUICKLIST
+ bool
+ default y
+
config MMU
bool
default y
diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
index 2153bcacbe6..94e57109fad 100644
--- a/arch/ia64/hp/common/hwsw_iommu.c
+++ b/arch/ia64/hp/common/hwsw_iommu.c
@@ -63,7 +63,7 @@ use_swiotlb (struct device *dev)
return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask);
}
-void
+void __init
hwsw_init (void)
{
/* default to a smallish 2MB sw I/O TLB */
diff --git a/arch/ia64/ia32/audit.c b/arch/ia64/ia32/audit.c
index 92d7d0c8d93..8850fe40ea3 100644
--- a/arch/ia64/ia32/audit.c
+++ b/arch/ia64/ia32/audit.c
@@ -20,6 +20,11 @@ unsigned ia32_read_class[] = {
~0U
};
+unsigned ia32_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
int ia32_classify_syscall(unsigned syscall)
{
switch(syscall) {
diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c
index 04682555a28..f3802ae89b1 100644
--- a/arch/ia64/kernel/audit.c
+++ b/arch/ia64/kernel/audit.c
@@ -23,6 +23,20 @@ static unsigned chattr_class[] = {
~0U
};
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+#ifdef CONFIG_IA32_SUPPORT
+ if (arch == AUDIT_ARCH_I386)
+ return 1;
+#endif
+ return 0;
+}
+
int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_IA32_SUPPORT
@@ -49,15 +63,18 @@ static int __init audit_classes_init(void)
extern __u32 ia32_write_class[];
extern __u32 ia32_read_class[];
extern __u32 ia32_chattr_class[];
+ extern __u32 ia32_signal_class[];
audit_register_class(AUDIT_CLASS_WRITE_32, ia32_write_class);
audit_register_class(AUDIT_CLASS_READ_32, ia32_read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class);
audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL_32, ia32_signal_class);
#endif
audit_register_class(AUDIT_CLASS_WRITE, write_class);
audit_register_class(AUDIT_CLASS_READ, read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
return 0;
}
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index b50bf208678..144b056282a 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1583,5 +1583,7 @@ sys_call_table:
data8 sys_vmsplice
data8 sys_ni_syscall // reserved for move_pages
data8 sys_getcpu
+ data8 sys_epoll_pwait // 1305
+ data8 sys_utimensat
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c
index 6a49600cf33..b642648cc2a 100644
--- a/arch/ia64/kernel/err_inject.c
+++ b/arch/ia64/kernel/err_inject.c
@@ -291,5 +291,5 @@ module_init(err_inject_init);
module_exit(err_inject_exit);
MODULE_AUTHOR("Fenghua Yu <fenghua.yu@intel.com>");
-MODULE_DESCRIPTION("MC error injection kenrel sysfs interface");
+MODULE_DESCRIPTION("MC error injection kernel sysfs interface");
MODULE_LICENSE("GPL");
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index ce49c85c928..b4c239685d2 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -104,6 +104,17 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
irq_redir[irq] = (char) (redir & 0xff);
}
}
+
+bool is_affinity_mask_valid(cpumask_t cpumask)
+{
+ if (ia64_platform_is("sn2")) {
+ /* Only allow one CPU to be specified in the smp_affinity mask */
+ if (cpus_weight(cpumask) != 1)
+ return false;
+ }
+ return true;
+}
+
#endif /* CONFIG_SMP */
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 4f5fd0960ba..72e593e9405 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -370,14 +370,18 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- kcb->prev_kprobe.kp = kprobe_running();
- kcb->prev_kprobe.status = kcb->kprobe_status;
+ unsigned int i;
+ i = atomic_add_return(1, &kcb->prev_kprobe_index);
+ kcb->prev_kprobe[i-1].kp = kprobe_running();
+ kcb->prev_kprobe[i-1].status = kcb->kprobe_status;
}
static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
- __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
- kcb->kprobe_status = kcb->prev_kprobe.status;
+ unsigned int i;
+ i = atomic_sub_return(1, &kcb->prev_kprobe_index);
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe[i].kp;
+ kcb->kprobe_status = kcb->prev_kprobe[i].status;
}
static void __kprobes set_current_kprobe(struct kprobe *p,
diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c
index 9620822270a..13df337508e 100644
--- a/arch/ia64/kernel/machvec.c
+++ b/arch/ia64/kernel/machvec.c
@@ -35,7 +35,7 @@ lookup_machvec (const char *name)
return 0;
}
-void
+void __init
machvec_init (const char *name)
{
struct ia64_machine_vector *mv;
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index f8ae709de0b..26814de6c29 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -118,7 +118,9 @@ static ia64_mc_info_t ia64_mc_info;
#define CPE_HISTORY_LENGTH 5
#define CMC_HISTORY_LENGTH 5
+#ifdef CONFIG_ACPI
static struct timer_list cpe_poll_timer;
+#endif
static struct timer_list cmc_poll_timer;
/*
* This variable tells whether we are currently in polling mode.
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index 44ce5ed9444..7ac8592a35b 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -88,7 +88,7 @@ void show_mem(void)
printk(KERN_INFO "%d pages shared\n", total_shared);
printk(KERN_INFO "%d pages swap cached\n", total_cached);
printk(KERN_INFO "Total of %ld pages in page table cache\n",
- pgtable_quicklist_total_size());
+ quicklist_total_size());
printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
}
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 94844442812..38085ac1833 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -561,7 +561,7 @@ void show_mem(void)
printk(KERN_INFO "%d pages shared\n", total_shared);
printk(KERN_INFO "%d pages swap cached\n", total_cached);
printk(KERN_INFO "Total of %ld pages in page table cache\n",
- pgtable_quicklist_total_size());
+ quicklist_total_size());
printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
}
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index cffb1e8325e..c14abefabaf 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -39,9 +39,6 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-DEFINE_PER_CPU(unsigned long *, __pgtable_quicklist);
-DEFINE_PER_CPU(long, __pgtable_quicklist_size);
-
extern void ia64_tlb_init (void);
unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
@@ -56,54 +53,6 @@ EXPORT_SYMBOL(vmem_map);
struct page *zero_page_memmap_ptr; /* map entry for zero page */
EXPORT_SYMBOL(zero_page_memmap_ptr);
-#define MIN_PGT_PAGES 25UL
-#define MAX_PGT_FREES_PER_PASS 16L
-#define PGT_FRACTION_OF_NODE_MEM 16
-
-static inline long
-max_pgt_pages(void)
-{
- u64 node_free_pages, max_pgt_pages;
-
-#ifndef CONFIG_NUMA
- node_free_pages = nr_free_pages();
-#else
- node_free_pages = node_page_state(numa_node_id(), NR_FREE_PAGES);
-#endif
- max_pgt_pages = node_free_pages / PGT_FRACTION_OF_NODE_MEM;
- max_pgt_pages = max(max_pgt_pages, MIN_PGT_PAGES);
- return max_pgt_pages;
-}
-
-static inline long
-min_pages_to_free(void)
-{
- long pages_to_free;
-
- pages_to_free = pgtable_quicklist_size - max_pgt_pages();
- pages_to_free = min(pages_to_free, MAX_PGT_FREES_PER_PASS);
- return pages_to_free;
-}
-
-void
-check_pgt_cache(void)
-{
- long pages_to_free;
-
- if (unlikely(pgtable_quicklist_size <= MIN_PGT_PAGES))
- return;
-
- preempt_disable();
- while (unlikely((pages_to_free = min_pages_to_free()) > 0)) {
- while (pages_to_free--) {
- free_page((unsigned long)pgtable_quicklist_alloc());
- }
- preempt_enable();
- preempt_disable();
- }
- preempt_enable();
-}
-
void
lazy_mmu_prot_update (pte_t pte)
{
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index d48bcd83253..7ed72d3faf7 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -364,7 +364,7 @@ void sn_bus_store_sysdata(struct pci_dev *dev)
element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL);
if (!element) {
- dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__);
+ dev_dbg(&dev->dev, "%s: out of memory!\n", __FUNCTION__);
return;
}
element->sysdata = SN_PCIDEV_INFO(dev);
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
index 57c723f5cba..7ba403232cb 100644
--- a/arch/ia64/sn/kernel/xpc_partition.c
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -574,7 +574,7 @@ xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version,
u64 remote_vars_pa, struct xpc_vars *remote_vars)
{
part->remote_rp_version = remote_rp_version;
- dev_dbg(xpc_part, " remote_rp_version = 0x%016lx\n",
+ dev_dbg(xpc_part, " remote_rp_version = 0x%016x\n",
part->remote_rp_version);
part->remote_rp_stamp = *remote_rp_stamp;
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c
index 88fad85ceef..da721353097 100644
--- a/arch/ia64/sn/kernel/xpnet.c
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -343,8 +343,8 @@ xpnet_dev_open(struct net_device *dev)
enum xpc_retval ret;
- dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %d, "
- "%d)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
+ dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
+ "%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS,
XPNET_MAX_IDLE_KTHREADS);
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 9740d6b8ae1..c3bb8a755b0 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -241,6 +241,10 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
+config SCHED_NO_NO_OMIT_FRAME_POINTER
+ bool
+ default y
+
config PREEMPT
bool "Preemptible Kernel"
help
diff --git a/arch/m32r/mm/mmu.S b/arch/m32r/mm/mmu.S
index 8bb74b10dca..49a6d16a3d5 100644
--- a/arch/m32r/mm/mmu.S
+++ b/arch/m32r/mm/mmu.S
@@ -163,7 +163,8 @@ ENTRY(tme_handler)
; pte_data = (unsigned long)pte_val(*pte);
ld r2, @r3 ; r2: pte data
- or3 r2, r2, #2 ; _PAGE_PRESENT(=2)
+ and3 r3, r2, #2 ; _PAGE_PRESENT(=2) check
+ beqz r3, 3f
.fillinsn
5:
@@ -264,11 +265,8 @@ ENTRY(tme_handler)
;
and3 r1, r1, #0xeff
ldi r4, #611 ; _KERNPG_TABLE(=611)
- beq r1, r4, 4f ; !pmd_bad(*pmd) ?
- .fillinsn
-3:
- ldi r1, #0 ; r1: pte_data = 0
- bra 5f
+ bne r1, r4, 3f ; !pmd_bad(*pmd) ?
+
.fillinsn
4:
; pte = pte_offset(pmd, address);
@@ -282,8 +280,10 @@ ENTRY(tme_handler)
add r4, r3 ; r4: pte
; pte_data = (unsigned long)pte_val(*pte);
ld r1, @r4 ; r1: pte_data
- .fillinsn
+ and3 r3, r1, #2 ; _PAGE_PRESENT(=2) check
+ beqz r3, 3f
+ .fillinsn
;; set tlb
; r0: address, r1: pte_data, r2: entry
; r3,r4: (free)
@@ -295,8 +295,7 @@ ENTRY(tme_handler)
and3 r4, r4, #(MMU_CONTEXT_ASID_MASK)
or r3, r4
st r3, @r2
- or3 r4, r1, #2 ; _PAGE_PRESENT(=2)
- st r4, @(4,r2) ; set_tlb_data(entry, pte_data);
+ st r1, @(4,r2) ; set_tlb_data(entry, pte_data);
ld r4, @sp+
ld r3, @sp+
@@ -306,6 +305,11 @@ ENTRY(tme_handler)
ld sp, @sp+
rte
+ .fillinsn
+3:
+ ldi r1, #2 ; r1: pte_data = 0 | _PAGE_PRESENT(=2)
+ bra 5b
+
#else
#error unknown isa configuration
#endif
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 16ecea3c081..0f09412e1b7 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -15,121 +15,8 @@ choice
prompt "System type"
default SGI_IP22
-config MIPS_MTX1
- bool "4G Systems MTX-1 board"
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select RESOURCES_64BIT if PCI
- select SOC_AU1500
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_BOSPORUS
- bool "AMD Alchemy Bosporus board"
- select SOC_AU1500
- select DMA_NONCOHERENT
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_PB1000
- bool "AMD Alchemy PB1000 board"
- select SOC_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select RESOURCES_64BIT if PCI
- select SWAP_IO_SPACE
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_PB1100
- bool "AMD Alchemy PB1100 board"
- select SOC_AU1100
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select RESOURCES_64BIT if PCI
- select SWAP_IO_SPACE
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_PB1500
- bool "AMD Alchemy PB1500 board"
- select SOC_AU1500
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select RESOURCES_64BIT if PCI
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_PB1550
- bool "AMD Alchemy PB1550 board"
- select SOC_AU1550
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select MIPS_DISABLE_OBSOLETE_IDE
- select RESOURCES_64BIT if PCI
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_PB1200
- bool "AMD Alchemy PB1200 board"
- select SOC_AU1200
- select DMA_NONCOHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
- select RESOURCES_64BIT if PCI
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_DB1000
- bool "AMD Alchemy DB1000 board"
- select SOC_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select RESOURCES_64BIT if PCI
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_DB1100
- bool "AMD Alchemy DB1100 board"
- select SOC_AU1100
- select DMA_NONCOHERENT
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_DB1500
- bool "AMD Alchemy DB1500 board"
- select SOC_AU1500
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select MIPS_DISABLE_OBSOLETE_IDE
- select RESOURCES_64BIT if PCI
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_BIG_ENDIAN
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_DB1550
- bool "AMD Alchemy DB1550 board"
- select SOC_AU1550
- select HW_HAS_PCI
- select DMA_NONCOHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
- select RESOURCES_64BIT if PCI
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_DB1200
- bool "AMD Alchemy DB1200 board"
- select SOC_AU1200
- select DMA_COHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
-config MIPS_MIRAGE
- bool "AMD Alchemy Mirage board"
- select DMA_NONCOHERENT
- select SOC_AU1500
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_LITTLE_ENDIAN
+config MACH_ALCHEMY
+ bool "Alchemy processor based machines"
config BASLER_EXCITE
bool "Basler eXcite smart camera"
@@ -369,28 +256,6 @@ config MIPS_SIM
This option enables support for MIPS Technologies MIPSsim software
emulator.
-config MOMENCO_JAGUAR_ATX
- bool "Momentum Jaguar board"
- select BOOT_ELF32
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select IRQ_CPU
- select IRQ_CPU_RM7K
- select IRQ_MV64340
- select LIMITED_DMA
- select PCI_MARVELL
- select RM7000_CPU_SCACHE
- select SWAP_IO_SPACE
- select SYS_HAS_CPU_RM9000
- select SYS_HAS_EARLY_PRINTK
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL
- select SYS_SUPPORTS_BIG_ENDIAN
- select SYS_SUPPORTS_KGDB
- help
- The Jaguar ATX is a MIPS-based Single Board Computer (SBC) made by
- Momentum Computer <http://www.momenco.com/>.
-
config MOMENCO_OCELOT
bool "Momentum Ocelot board"
select DMA_NONCOHERENT
@@ -446,29 +311,6 @@ config MOMENCO_OCELOT_C
The Ocelot is a MIPS-based Single Board Computer (SBC) made by
Momentum Computer <http://www.momenco.com/>.
-config MOMENCO_OCELOT_G
- bool "Momentum Ocelot-G board"
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select IRQ_CPU
- select IRQ_CPU_RM7K
- select PCI_MARVELL
- select RM7000_CPU_SCACHE
- select SWAP_IO_SPACE
- select SYS_HAS_CPU_RM7000
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
- select SYS_SUPPORTS_BIG_ENDIAN
- help
- The Ocelot is a MIPS-based Single Board Computer (SBC) made by
- Momentum Computer <http://www.momenco.com/>.
-
-config MIPS_XXS1500
- bool "MyCable XXS1500 board"
- select DMA_NONCOHERENT
- select SOC_AU1500
- select SYS_SUPPORTS_LITTLE_ENDIAN
-
config PNX8550_JBS
bool "Philips PNX8550 based JBS board"
select PNX8550
@@ -775,7 +617,6 @@ config TOSHIBA_JMR3927
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_BIG_ENDIAN
- select TOSHIBA_BOARDS
select GENERIC_HARDIRQS_NO__DO_IRQ
config TOSHIBA_RBTX4927
@@ -791,7 +632,6 @@ config TOSHIBA_RBTX4927
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_KGDB
- select TOSHIBA_BOARDS
select GENERIC_HARDIRQS_NO__DO_IRQ
help
This Toshiba board is based on the TX4927 processor. Say Y here to
@@ -811,7 +651,6 @@ config TOSHIBA_RBTX4938
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_KGDB
- select TOSHIBA_BOARDS
select GENERIC_HARDIRQS_NO__DO_IRQ
help
This Toshiba board is based on the TX4938 processor. Say Y here to
@@ -819,11 +658,11 @@ config TOSHIBA_RBTX4938
endchoice
+source "arch/mips/au1000/Kconfig"
source "arch/mips/ddb5xxx/Kconfig"
source "arch/mips/gt64120/ev64120/Kconfig"
source "arch/mips/jazz/Kconfig"
source "arch/mips/lasat/Kconfig"
-source "arch/mips/momentum/Kconfig"
source "arch/mips/pmc-sierra/Kconfig"
source "arch/mips/sgi-ip27/Kconfig"
source "arch/mips/sibyte/Kconfig"
@@ -923,11 +762,6 @@ config GENERIC_ISA_DMA
config I8259
bool
-config LIMITED_DMA
- bool
- select HIGHMEM
- select SYS_SUPPORTS_HIGHMEM
-
config MIPS_BONITO64
bool
@@ -1013,33 +847,6 @@ config MIPS_RM9122
config PCI_MARVELL
bool
-config SOC_AU1000
- bool
- select SOC_AU1X00
-
-config SOC_AU1100
- bool
- select SOC_AU1X00
-
-config SOC_AU1500
- bool
- select SOC_AU1X00
-
-config SOC_AU1550
- bool
- select SOC_AU1X00
-
-config SOC_AU1200
- bool
- select SOC_AU1X00
-
-config SOC_AU1X00
- bool
- select SYS_HAS_CPU_MIPS32_R1
- select SYS_SUPPORTS_32BIT_KERNEL
- select SYS_SUPPORTS_APM_EMULATION
- select SYS_SUPPORTS_KGDB
-
config SERIAL_RM9000
bool
@@ -1081,9 +888,9 @@ config WDT_RM9000
choice
prompt "Galileo Chip Clock"
#default SYSCLK_83 if MIPS_EV64120
- depends on MIPS_EV64120 || MOMENCO_OCELOT || MOMENCO_OCELOT_G
+ depends on MIPS_EV64120 || MOMENCO_OCELOT
default SYSCLK_83 if MIPS_EV64120
- default SYSCLK_100 if MOMENCO_OCELOT || MOMENCO_OCELOT_G
+ default SYSCLK_100 if MOMENCO_OCELOT
config SYSCLK_75
bool "75" if MIPS_EV64120
@@ -1092,7 +899,7 @@ config SYSCLK_83
bool "83.3" if MIPS_EV64120
config SYSCLK_100
- bool "100" if MIPS_EV64120 || MOMENCO_OCELOT || MOMENCO_OCELOT_G
+ bool "100" if MIPS_EV64120 || MOMENCO_OCELOT
endchoice
@@ -1131,9 +938,6 @@ config ARC64
config BOOT_ELF64
bool
-config TOSHIBA_BOARDS
- bool
-
menu "CPU selection"
choice
@@ -1557,6 +1361,7 @@ config MIPS_MT_SMP
bool "Use 1 TC on each available VPE for SMP"
depends on SYS_SUPPORTS_MULTITHREADING
select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
select CPU_MIPSR2_SRS
select MIPS_MT
select NR_CPUS_DEFAULT_2
@@ -1572,6 +1377,7 @@ config MIPS_MT_SMTC
#depends on CPU_MIPS64_R2 # once there is hardware ...
depends on SYS_SUPPORTS_MULTITHREADING
select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
select CPU_MIPSR2_SRS
select MIPS_MT
select NR_CPUS_DEFAULT_8
@@ -1584,6 +1390,8 @@ config MIPS_MT_SMTC
config MIPS_VPE_LOADER
bool "VPE loader support."
depends on SYS_SUPPORTS_MULTITHREADING
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
select MIPS_MT
help
Includes a loader for loading an elf relocatable object
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 4892db88a86..f450066b624 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -343,15 +343,6 @@ cflags-$(CONFIG_MOMENCO_OCELOT) += -Iinclude/asm-mips/mach-ocelot
load-$(CONFIG_MOMENCO_OCELOT) += 0xffffffff80100000
#
-# Momentum Ocelot-G board
-#
-# The Ocelot-G setup.o must be linked early - it does the ioremap() for the
-# mips_io_port_base.
-#
-core-$(CONFIG_MOMENCO_OCELOT_G) += arch/mips/momentum/ocelot_g/
-load-$(CONFIG_MOMENCO_OCELOT_G) += 0xffffffff80100000
-
-#
# Momentum Ocelot-C and -CS boards
#
# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the
@@ -388,17 +379,6 @@ cflags-$(CONFIG_BASLER_EXCITE) += -Iinclude/asm-mips/mach-excite
load-$(CONFIG_BASLER_EXCITE) += 0x80100000
#
-# Momentum Jaguar ATX
-#
-core-$(CONFIG_MOMENCO_JAGUAR_ATX) += arch/mips/momentum/jaguar_atx/
-cflags-$(CONFIG_MOMENCO_JAGUAR_ATX) += -Iinclude/asm-mips/mach-ja
-#ifdef CONFIG_JAGUAR_DMALOW
-#load-$(CONFIG_MOMENCO_JAGUAR_ATX) += 0xffffffff88000000
-#else
-load-$(CONFIG_MOMENCO_JAGUAR_ATX) += 0xffffffff80100000
-#endif
-
-#
# NEC DDB
#
core-$(CONFIG_DDB5XXX_COMMON) += arch/mips/ddb5xxx/common/
@@ -729,3 +709,25 @@ archclean:
CLEAN_FILES += vmlinux.32 \
vmlinux.64 \
vmlinux.ecoff
+
+quiet_cmd_syscalls_n32 = CALL-N32 $<
+ cmd_syscalls_n32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=n32
+
+quiet_cmd_syscalls_o32 = CALL-O32 $<
+ cmd_syscalls_o32 = $(CONFIG_SHELL) $< $(CC) $(c_flags) -mabi=32
+
+PHONY += missing-syscalls-n32 missing-syscalls-o32
+
+missing-syscalls-n32: scripts/checksyscalls.sh FORCE
+ $(call cmd,syscalls_n32)
+
+missing-syscalls-o32: scripts/checksyscalls.sh FORCE
+ $(call cmd,syscalls_o32)
+
+archprepare:
+ifdef CONFIG_MIPS32_N32
+ $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-n32
+endif
+ifdef CONFIG_MIPS32_O32
+ $(Q)$(MAKE) $(build)=arch/mips missing-syscalls-o32
+endif
diff --git a/arch/mips/au1000/Kconfig b/arch/mips/au1000/Kconfig
new file mode 100644
index 00000000000..abea8809825
--- /dev/null
+++ b/arch/mips/au1000/Kconfig
@@ -0,0 +1,142 @@
+choice
+ prompt "Machine type"
+ depends on MACH_ALCHEMY
+ default MIPS_DB1000
+
+config MIPS_MTX1
+ bool "4G Systems MTX-1 board"
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_BOSPORUS
+ bool "Alchemy Bosporus board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_DB1000
+ bool "Alchemy DB1000 board"
+ select SOC_AU1000
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_DB1100
+ bool "Alchemy DB1100 board"
+ select SOC_AU1100
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_DB1200
+ bool "Alchemy DB1200 board"
+ select SOC_AU1200
+ select DMA_COHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_DB1500
+ bool "Alchemy DB1500 board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_DB1550
+ bool "Alchemy DB1550 board"
+ select SOC_AU1550
+ select HW_HAS_PCI
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_MIRAGE
+ bool "Alchemy Mirage board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_PB1000
+ bool "Alchemy PB1000 board"
+ select SOC_AU1000
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_PB1100
+ bool "Alchemy PB1100 board"
+ select SOC_AU1100
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_PB1200
+ bool "Alchemy PB1200 board"
+ select SOC_AU1200
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_PB1500
+ bool "Alchemy PB1500 board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select RESOURCES_64BIT if PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_PB1550
+ bool "Alchemy PB1550 board"
+ select SOC_AU1550
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select RESOURCES_64BIT if PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MIPS_XXS1500
+ bool "MyCable XXS1500 board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+endchoice
+
+config SOC_AU1000
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1100
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1500
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1550
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1200
+ bool
+ select SOC_AU1X00
+
+config SOC_AU1X00
+ bool
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_APM_EMULATION
+ select SYS_SUPPORTS_KGDB
diff --git a/arch/mips/basler/excite/excite_device.c b/arch/mips/basler/excite/excite_device.c
index cc1ce77eab4..e00bc2d7f30 100644
--- a/arch/mips/basler/excite/excite_device.c
+++ b/arch/mips/basler/excite/excite_device.c
@@ -68,7 +68,7 @@ enum {
static struct resource
- excite_ctr_resource __attribute__((unused)) = {
+ excite_ctr_resource __maybe_unused = {
.name = "GPI counters",
.start = 0,
.end = 5,
@@ -77,7 +77,7 @@ static struct resource
.sibling = NULL,
.child = NULL
},
- excite_gpislice_resource __attribute__((unused)) = {
+ excite_gpislice_resource __maybe_unused = {
.name = "GPI slices",
.start = 0,
.end = 1,
@@ -86,7 +86,7 @@ static struct resource
.sibling = NULL,
.child = NULL
},
- excite_mdio_channel_resource __attribute__((unused)) = {
+ excite_mdio_channel_resource __maybe_unused = {
.name = "MDIO channels",
.start = 0,
.end = 1,
@@ -95,7 +95,7 @@ static struct resource
.sibling = NULL,
.child = NULL
},
- excite_fifomem_resource __attribute__((unused)) = {
+ excite_fifomem_resource __maybe_unused = {
.name = "FIFO memory",
.start = 0,
.end = 767,
@@ -104,7 +104,7 @@ static struct resource
.sibling = NULL,
.child = NULL
},
- excite_scram_resource __attribute__((unused)) = {
+ excite_scram_resource __maybe_unused = {
.name = "Scratch RAM",
.start = EXCITE_PHYS_SCRAM,
.end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1,
@@ -113,7 +113,7 @@ static struct resource
.sibling = NULL,
.child = NULL
},
- excite_fpga_resource __attribute__((unused)) = {
+ excite_fpga_resource __maybe_unused = {
.name = "System FPGA",
.start = EXCITE_PHYS_FPGA,
.end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1,
@@ -122,7 +122,7 @@ static struct resource
.sibling = NULL,
.child = NULL
},
- excite_nand_resource __attribute__((unused)) = {
+ excite_nand_resource __maybe_unused = {
.name = "NAND flash control",
.start = EXCITE_PHYS_NAND,
.end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1,
@@ -131,7 +131,7 @@ static struct resource
.sibling = NULL,
.child = NULL
},
- excite_titan_resource __attribute__((unused)) = {
+ excite_titan_resource __maybe_unused = {
.name = "TITAN registers",
.start = EXCITE_PHYS_TITAN,
.end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1,
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 9565b2104dc..c292f80a8c7 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,7 +2,7 @@
# Makefile for the Cobalt micro systems family specific parts of the kernel
#
-obj-y := irq.o reset.o setup.o buttons.o
+obj-y := buttons.o irq.o reset.o rtc.o serial.o setup.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_EARLY_PRINTK) += console.o
diff --git a/arch/mips/cobalt/rtc.c b/arch/mips/cobalt/rtc.c
new file mode 100644
index 00000000000..284daefc5c5
--- /dev/null
+++ b/arch/mips/cobalt/rtc.c
@@ -0,0 +1,63 @@
+/*
+ * Registration of Cobalt RTC platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+static struct resource cobalt_rtc_resource[] __initdata = {
+ {
+ .start = 0x70,
+ .end = 0x77,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static __init int cobalt_rtc_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ pdev = platform_device_alloc("rtc_cmos", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ retval = platform_device_add_resources(pdev, cobalt_rtc_resource,
+ ARRAY_SIZE(cobalt_rtc_resource));
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(cobalt_rtc_add);
diff --git a/arch/mips/cobalt/serial.c b/arch/mips/cobalt/serial.c
new file mode 100644
index 00000000000..c27116599a5
--- /dev/null
+++ b/arch/mips/cobalt/serial.c
@@ -0,0 +1,85 @@
+/*
+ * Registration of Cobalt UART platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <cobalt.h>
+
+static struct resource cobalt_uart_resource[] __initdata = {
+ {
+ .start = 0x1c800000,
+ .end = 0x1c800007,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = COBALT_SERIAL_IRQ,
+ .end = COBALT_SERIAL_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct plat_serial8250_port cobalt_serial8250_port[] = {
+ {
+ .irq = COBALT_SERIAL_IRQ,
+ .uartclk = 18432000,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .mapbase = 0x1c800000,
+ },
+ {},
+};
+
+static __init int cobalt_uart_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ /*
+ * Cobalt Qube1 and RAQ1 have no UART.
+ */
+ if (cobalt_board_id <= COBALT_BRD_ID_RAQ1)
+ return 0;
+
+ pdev = platform_device_alloc("serial8250", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->id = PLAT8250_DEV_PLATFORM;
+ pdev->dev.platform_data = cobalt_serial8250_port;
+
+ retval = platform_device_add_resources(pdev, cobalt_uart_resource, ARRAY_SIZE(cobalt_uart_resource));
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(cobalt_uart_add);
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index d0dd81790f7..7abe45e7842 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -10,11 +10,8 @@
*
*/
#include <linux/interrupt.h>
-#include <linux/pci.h>
#include <linux/init.h>
#include <linux/pm.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
@@ -27,9 +24,6 @@
extern void cobalt_machine_restart(char *command);
extern void cobalt_machine_halt(void);
extern void cobalt_machine_power_off(void);
-extern void cobalt_early_console(void);
-
-int cobalt_board_id;
const char *get_system_type(void)
{
@@ -95,8 +89,6 @@ static struct resource cobalt_reserved_resources[] = {
void __init plat_mem_setup(void)
{
- static struct uart_port uart;
- unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
int i;
_machine_restart = cobalt_machine_restart;
@@ -111,29 +103,6 @@ void __init plat_mem_setup(void)
/* These resources have been reserved by VIA SuperI/O chip. */
for (i = 0; i < ARRAY_SIZE(cobalt_reserved_resources); i++)
request_resource(&ioport_resource, cobalt_reserved_resources + i);
-
- /* Read the cobalt id register out of the PCI config space */
- PCI_CFG_SET(devfn, (VIA_COBALT_BRD_ID_REG & ~0x3));
- cobalt_board_id = GT_READ(GT_PCI0_CFGDATA_OFS);
- cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8);
- cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
-
- printk("Cobalt board ID: %d\n", cobalt_board_id);
-
- if (cobalt_board_id > COBALT_BRD_ID_RAQ1) {
-#ifdef CONFIG_SERIAL_8250
- uart.line = 0;
- uart.type = PORT_UNKNOWN;
- uart.uartclk = 18432000;
- uart.irq = COBALT_SERIAL_IRQ;
- uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF |
- UPF_SKIP_TEST;
- uart.iotype = UPIO_MEM;
- uart.mapbase = 0x1c800000;
-
- early_serial_setup(&uart);
-#endif
- }
}
/*
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index ba593b510b7..631b2138ad6 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:24 2007
+# Linux kernel version: 2.6.21-rc7
+# Wed Apr 18 14:25:45 2007
#
CONFIG_MIPS=y
@@ -62,7 +62,6 @@ CONFIG_MIPS_COBALT=y
# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_EARLY_PRINTK=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -74,12 +73,14 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_I8259=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_IRQ_CPU=y
-CONFIG_MIPS_GT64111=y
+CONFIG_PCI_GT64XXX_PCI0=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
@@ -179,6 +180,7 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
+# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
@@ -477,7 +479,6 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CDROM_PKTCDVD=y
CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not set
@@ -518,7 +519,7 @@ CONFIG_BLK_DEV_IDEPCI=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 is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
@@ -546,7 +547,6 @@ CONFIG_BLK_DEV_TC86C001=y
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
#
@@ -779,7 +779,8 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
-CONFIG_RTC=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
CONFIG_COBALT_LCD=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
@@ -815,6 +816,11 @@ CONFIG_COBALT_LCD=y
# CONFIG_HWMON_VID is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -827,7 +833,7 @@ CONFIG_COBALT_LCD=y
#
# Graphics support
#
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
#
@@ -835,7 +841,6 @@ CONFIG_COBALT_LCD=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -894,7 +899,29 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# Real Time Clock
#
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
#
# DMA Engine support
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 0db6a8b3730..10f6af43753 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 162add97c5e..4b086292774 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 82801ec43e6..820659e810d 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 545f23094e1..4050b9b91bc 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 5bd3b4328e5..7b3519058ab 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
deleted file mode 100644
index 083104daa2c..00000000000
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ /dev/null
@@ -1,897 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:33 2007
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_MIPS_SIM is not set
-CONFIG_MOMENCO_JAGUAR_ATX=y
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
-CONFIG_JAGUAR_DMALOW=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_LIMITED_DMA=y
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_IRQ_CPU_RM7K=y
-CONFIG_IRQ_MV64340=y
-CONFIG_PCI_MARVELL=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_BOOT_ELF32=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-
-#
-# CPU selection
-#
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-CONFIG_CPU_RM9000=y
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_RM9000=y
-CONFIG_WEAK_ORDERING=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-CONFIG_32BIT=y
-# CONFIG_64BIT is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_RM7000_CPU_SCACHE=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SHMEM=y
-CONFIG_SLAB=y
-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_MODVERSIONS is not set
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Power management options
-#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-# CONFIG_PACKET is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_IPV6=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_TUNNEL=m
-CONFIG_INET6_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETWORK_SECMARK=y
-# CONFIG_NETFILTER is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-CONFIG_IEEE80211_CRYPT_CCMP=m
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# 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
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-CONFIG_ATA_OVER_ETH=m
-
-#
-# Misc devices
-#
-CONFIG_SGI_IOC4=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_RAID_ATTRS=m
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_FIXED_PHY is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-CONFIG_EEPRO100=y
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_R8169 is not set
-# 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
-CONFIG_MV643XX_ETH=y
-CONFIG_QLA3XXX=m
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=m
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP 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
-
-#
-# Input device support
-#
-# CONFIG_INPUT is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-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_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK 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
-#
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=m
-CONFIG_GENERIC_ACL=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Kernel hacking
-#
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CROSSCOMPILE=y
-CONFIG_CMDLINE=""
-CONFIG_SYS_SUPPORTS_KGDB=y
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_TWOFISH_COMMON=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=m
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 068e48ec709..1b364cf6914 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -80,7 +80,6 @@ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_MIPS_TX3927=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_TOSHIBA_BOARDS=y
#
# CPU selection
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 69678d99ae6..37d696c6454 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 070672799da..b11f0e8b605 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 354e49b7a5f..2927f38f490 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -9,6 +9,7 @@ CONFIG_MIPS=y
# Machine selection
#
CONFIG_ZONE_DMA=y
+CONFIG_MACH_ALCHEMY=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/rbhma4200_defconfig
index 7078e6b3ea1..35d64260917 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/rbhma4200_defconfig
@@ -1,14 +1,13 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:36 2007
+# Linux kernel version: 2.6.21
+# Wed May 9 23:44:19 2007
#
CONFIG_MIPS=y
#
# Machine selection
#
-CONFIG_ZONE_DMA=y
# CONFIG_MIPS_MTX1 is not set
# CONFIG_MIPS_BOSPORUS is not set
# CONFIG_MIPS_PB1000 is not set
@@ -33,11 +32,9 @@ CONFIG_ZONE_DMA=y
# CONFIG_MIPS_SEAD is not set
# CONFIG_WR_PPMC is not set
# CONFIG_MIPS_SIM is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
# CONFIG_MOMENCO_OCELOT is not set
# CONFIG_MOMENCO_OCELOT_3 is not set
# CONFIG_MOMENCO_OCELOT_C is not set
-CONFIG_MOMENCO_OCELOT_G=y
# CONFIG_MIPS_XXS1500 is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
@@ -60,8 +57,9 @@ CONFIG_MOMENCO_OCELOT_G=y
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM is not set
# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
+CONFIG_TOSHIBA_RBTX4927=y
# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_TOSHIBA_FPCIB0 is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -70,19 +68,15 @@ CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_TIME=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_I8259=y
CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_IRQ_CPU_RM7K=y
-CONFIG_PCI_MARVELL=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_SWAP_IO_SPACE=y
-# CONFIG_SYSCLK_75 is not set
-# CONFIG_SYSCLK_83 is not set
-CONFIG_SYSCLK_100=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
#
@@ -97,18 +91,19 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_CPU_VR41XX is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_TX49XX=y
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_R10000 is not set
-CONFIG_CPU_RM7000=y
+# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_RM7000=y
+CONFIG_SYS_HAS_CPU_TX49XX=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
@@ -121,19 +116,15 @@ CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_RM7000_CPU_SCACHE=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -143,17 +134,17 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
# CONFIG_HZ_48 is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
+CONFIG_HZ_250=y
# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
# CONFIG_HZ_1024 is not set
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=250
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
@@ -183,34 +174,42 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_TASKSTATS is not set
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_SYSFS_DEPRECATED=y
-CONFIG_RELAY=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
+# CONFIG_HOTPLUG is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
CONFIG_SHMEM=y
-CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
#
# Loadable module support
#
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
#
# Block layer
@@ -218,7 +217,7 @@ CONFIG_BASE_SMALL=0
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_LSF=y
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -238,17 +237,12 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
#
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_MMU=y
#
# PCCARD (PCMCIA/CardBus) support
#
-# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
#
# Executable file formats
@@ -260,10 +254,7 @@ CONFIG_TRAD_SIGNALS=y
#
# Power management options
#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
+# CONFIG_PM is not set
#
# Networking
@@ -273,25 +264,21 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
+# CONFIG_NET_KEY is not set
CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_DHCP is not set
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
@@ -299,19 +286,19 @@ CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
+# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
#
@@ -352,13 +339,16 @@ CONFIG_NETWORK_SECMARK=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_CRYPT_CCMP=y
-CONFIG_IEEE80211_SOFTMAC=y
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
-CONFIG_WIRELESS_EXT=y
+# 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
#
# Device Drivers
@@ -369,18 +359,12 @@ CONFIG_WIRELESS_EXT=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
#
-CONFIG_CONNECTOR=y
-CONFIG_PROC_EVENTS=y
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
#
@@ -401,21 +385,24 @@ CONFIG_PROC_EVENTS=y
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_CDROM_PKTCDVD=y
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
#
# Misc devices
#
-CONFIG_SGI_IOC4=y
+# CONFIG_PHANTOM 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
@@ -425,7 +412,7 @@ CONFIG_SGI_IOC4=y
#
# SCSI device support
#
-CONFIG_RAID_ATTRS=y
+# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_NETLINK is not set
@@ -471,27 +458,13 @@ CONFIG_NETDEVICES=y
#
# PHY device support
#
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_FIXED_PHY is not set
+# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_GALILEO_64240_ETH=y
+# CONFIG_MII is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
@@ -503,6 +476,7 @@ CONFIG_GALILEO_64240_ETH=y
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
+CONFIG_NE2000=y
# CONFIG_NET_PCI is not set
#
@@ -521,18 +495,18 @@ CONFIG_GALILEO_64240_ETH=y
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
-CONFIG_QLA3XXX=y
+# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3=y
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
-CONFIG_NETXEN_NIC=y
+# CONFIG_NETXEN_NIC is not set
#
# Token Ring devices
@@ -540,9 +514,10 @@ CONFIG_NETXEN_NIC=y
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
# Wan interfaces
@@ -570,29 +545,7 @@ CONFIG_NETXEN_NIC=y
#
# Input device support
#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
+# CONFIG_INPUT is not set
#
# Hardware I/O ports
@@ -601,34 +554,31 @@ CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-CONFIG_SERIO_RAW=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_TXX9=y
+CONFIG_HAS_TXX9_SERIAL=y
+CONFIG_SERIAL_TXX9_NR_UARTS=6
+CONFIG_SERIAL_TXX9_CONSOLE=y
+CONFIG_SERIAL_TXX9_STDSERIAL=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
@@ -656,10 +606,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# TPM devices
#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
# CONFIG_I2C is not set
#
@@ -672,12 +619,12 @@ CONFIG_LEGACY_PTY_COUNT=256
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
+# CONFIG_HWMON is not set
#
-# Hardware Monitoring support
+# Multifunction device drivers
#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
@@ -692,15 +639,14 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# Graphics support
#
-# CONFIG_FIRMWARE_EDID is not set
-# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Console display driver support
+# Display device support
#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_FB is not set
#
# Sound
@@ -708,11 +654,6 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
#
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -728,10 +669,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
#
@@ -759,7 +696,40 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# Real Time Clock
#
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+CONFIG_RTC_DRV_DS1742=y
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
#
# DMA Engine support
@@ -785,9 +755,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
# File systems
#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
@@ -801,10 +769,10 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
+# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
-CONFIG_FUSE_FS=y
+# CONFIG_FUSE_FS is not set
CONFIG_GENERIC_ACL=y
#
@@ -824,21 +792,20 @@ CONFIG_GENERIC_ACL=y
# Pseudo filesystems
#
CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
+# CONFIG_PROC_KCORE is not set
CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-CONFIG_CONFIGFS_FS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
@@ -855,17 +822,17 @@ CONFIG_CONFIGFS_FS=y
# Network File Systems
#
CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
-CONFIG_EXPORTFS=y
+CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -889,10 +856,7 @@ CONFIG_MSDOS_PARTITION=y
#
# Distributed Lock Manager
#
-CONFIG_DLM=y
-CONFIG_DLM_TCP=y
-# CONFIG_DLM_SCTP is not set
-# CONFIG_DLM_DEBUG is not set
+# CONFIG_DLM is not set
#
# Profiling support
@@ -910,72 +874,29 @@ CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
#
# Security options
#
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_WP512=y
-CONFIG_CRYPTO_TGR192=y
-CONFIG_CRYPTO_GF128MUL=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_LRW=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_FCRYPT=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_TWOFISH_COMMON=y
-CONFIG_CRYPTO_SERPENT=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
-CONFIG_CRYPTO_TEA=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_KHAZAD=y
-CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CAMELLIA=y
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=y
+# CONFIG_CRC16 is not set
CONFIG_CRC32=y
-CONFIG_LIBCRC32C=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+# CONFIG_LIBCRC32C is not set
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 7d0f2174614..41011f770a6 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -89,7 +89,6 @@ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_HAVE_STD_PC_SERIAL_PORT=y
-CONFIG_TOSHIBA_BOARDS=y
#
# CPU selection
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0219_defconfig
index 1756d2bdf6b..8b1675c07ec 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0219_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:41 2007
+# Linux kernel version: 2.6.21-rc6
+# Sun Apr 15 01:06:01 2007
#
CONFIG_MIPS=y
@@ -66,10 +66,11 @@ CONFIG_MACH_VR41XX=y
# CONFIG_IBM_WORKPAD is not set
# CONFIG_NEC_CMBVR4133 is not set
CONFIG_TANBAC_TB022X=y
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0287 is not set
# CONFIG_VICTOR_MPC30X is not set
# CONFIG_ZAO_CAPCELLA is not set
+CONFIG_TANBAC_TB0219=y
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0287 is not set
CONFIG_PCI_VR41XX=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
@@ -184,6 +185,7 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
@@ -375,7 +377,7 @@ CONFIG_FIB_RULES=y
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
# CONFIG_SYS_HYPERVISOR is not set
#
@@ -415,7 +417,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -646,7 +647,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-CONFIG_TANBAC_TB0219=y
+CONFIG_GPIO_TB0219=y
# CONFIG_DRM is not set
CONFIG_GPIO_VR41XX=y
# CONFIG_RAW_DRIVER is not set
@@ -679,6 +680,11 @@ CONFIG_GPIO_VR41XX=y
# CONFIG_HWMON_VID is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -692,7 +698,7 @@ CONFIG_GPIO_VR41XX=y
#
# Graphics support
#
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
#
@@ -700,7 +706,6 @@ CONFIG_GPIO_VR41XX=y
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -831,6 +836,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
#
diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c
index 4fa54b230c0..9dccfa4752b 100644
--- a/arch/mips/kernel/early_printk.c
+++ b/arch/mips/kernel/early_printk.c
@@ -12,7 +12,8 @@
extern void prom_putchar(char);
-static void early_console_write(struct console *con, const char *s, unsigned n)
+static void __init
+early_console_write(struct console *con, const char *s, unsigned n)
{
while (n-- && *s) {
if (*s == '\n')
@@ -22,14 +23,20 @@ static void early_console_write(struct console *con, const char *s, unsigned n)
}
}
-static struct console early_console = {
+static struct console early_console __initdata = {
.name = "early",
.write = early_console_write,
.flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1
};
+static int early_console_initialized __initdata;
+
void __init setup_early_printk(void)
{
+ if (early_console_initialized)
+ return;
+ early_console_initialized = 1;
+
register_console(&early_console);
}
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 2967537221e..410868b5ea5 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -132,11 +132,11 @@ struct irq_chip msc_edgeirq_type = {
};
-void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq)
+void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqmap_t *imp, int nirq)
{
extern void (*board_bind_eic_interrupt)(unsigned int irq, unsigned int regset);
- _icctrl_msc = (unsigned long) ioremap (MIPS_MSC01_IC_REG_BASE, 0x40000);
+ _icctrl_msc = (unsigned long) ioremap (icubase, 0x40000);
/* Reset interrupt controller - initialises all registers to 0 */
MSCIC_WRITE(MSC01_IC_RST, MSC01_IC_RST_RST_BIT);
@@ -148,14 +148,14 @@ void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq)
switch (imp->im_type) {
case MSC01_IRQ_EDGE:
- set_irq_chip(base+n, &msc_edgeirq_type);
+ set_irq_chip(irqbase+n, &msc_edgeirq_type);
if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
else
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
break;
case MSC01_IRQ_LEVEL:
- set_irq_chip(base+n, &msc_levelirq_type);
+ set_irq_chip(irqbase+n, &msc_levelirq_type);
if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
else
@@ -163,7 +163,7 @@ void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq)
}
}
- irq_base = base;
+ irq_base = irqbase;
MSCIC_WRITE(MSC01_IC_GENA, MSC01_IC_GENA_GENA_BIT); /* Enable interrupt generation */
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 2fe4c868a80..aeded6c17de 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -28,7 +28,7 @@
static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
-int __devinit allocate_irqno(void)
+int allocate_irqno(void)
{
int irq;
@@ -59,7 +59,7 @@ void __init alloc_legacy_irqno(void)
BUG_ON(test_and_set_bit(i, irq_map));
}
-void __devinit free_irqno(unsigned int irq)
+void free_irqno(unsigned int irq)
{
smp_mb__before_clear_bit();
clear_bit(irq, irq_map);
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index e5e56bd498d..751b4a18b13 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -306,7 +306,7 @@ static unsigned int __init calibrate_hpt(void)
struct clocksource clocksource_mips = {
.name = "MIPS",
- .mask = 0xffffffff,
+ .mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index ff45a4b8fba..200de027f35 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -927,9 +927,9 @@ asmlinkage void do_reserved(struct pt_regs *regs)
(regs->cp0_cause & 0x7f) >> 2);
}
-asmlinkage void do_default_vi(struct pt_regs *regs)
+static asmlinkage void do_default_vi(void)
{
- show_regs(regs);
+ show_regs(get_irq_regs());
panic("Caught unexpected vectored interrupt.");
}
@@ -1128,7 +1128,7 @@ void mips_srs_free(int set)
clear_bit(set, &sr->sr_allocated);
}
-static void *set_vi_srs_handler(int n, void *addr, int srs)
+static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
{
unsigned long handler;
unsigned long old_handler = vi_handlers[n];
@@ -1217,7 +1217,7 @@ static void *set_vi_srs_handler(int n, void *addr, int srs)
return (void *)old_handler;
}
-void *set_vi_handler(int n, void *addr)
+void *set_vi_handler(int n, vi_handler_t addr)
{
return set_vi_srs_handler(n, addr, 0);
}
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index d7d3b14dcfb..5dad13efba7 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -9,4 +9,4 @@ obj-y += iomap.o
obj-$(CONFIG_PCI) += iomap-pci.o
# libgcc-style stuff needed in the kernel
-lib-y += ashldi3.o ashrdi3.o lshrdi3.o
+lib-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c
new file mode 100644
index 00000000000..e9ff258ef02
--- /dev/null
+++ b/arch/mips/lib/ucmpdi2.c
@@ -0,0 +1,19 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+word_type __ucmpdi2 (unsigned long a, unsigned long b)
+{
+ const DWunion au = {.ll = a};
+ const DWunion bu = {.ll = b};
+
+ if ((unsigned int) au.s.high < (unsigned int) bu.s.high)
+ return 0;
+ else if ((unsigned int) au.s.high > (unsigned int) bu.s.high)
+ return 2;
+ if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
+ return 0;
+ else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
+ return 2;
+ return 1;
+}
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index 83d76025d61..1cd830e3d93 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -311,16 +311,21 @@ void __init arch_init_irq(void)
if (!cpu_has_veic)
mips_cpu_irq_init();
- switch(mips_revision_corid) {
- case MIPS_REVISION_CORID_CORE_MSC:
- case MIPS_REVISION_CORID_CORE_FPGA2:
- case MIPS_REVISION_CORID_CORE_FPGA3:
- case MIPS_REVISION_CORID_CORE_24K:
- case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ switch(mips_revision_sconid) {
+ case MIPS_REVISION_SCON_SOCIT:
+ case MIPS_REVISION_SCON_ROCIT:
+ if (cpu_has_veic)
+ init_msc_irqs (MIPS_MSC01_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs);
+ else
+ init_msc_irqs (MIPS_MSC01_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs);
+ break;
+
+ case MIPS_REVISION_SCON_SOCITSC:
+ case MIPS_REVISION_SCON_SOCITSCP:
if (cpu_has_veic)
- init_msc_irqs (MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs);
+ init_msc_irqs (MIPS_SOCITSC_IC_REG_BASE, MSC01E_INT_BASE, msc_eicirqmap, msc_nr_eicirqs);
else
- init_msc_irqs (MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs);
+ init_msc_irqs (MIPS_SOCITSC_IC_REG_BASE, MSC01C_INT_BASE, msc_irqmap, msc_nr_irqs);
}
if (cpu_has_veic) {
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 675502ada5a..10dd2af2343 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -80,7 +80,6 @@ void __kunmap_atomic(void *kvaddr, enum km_type type)
pagefault_enable();
}
-#ifndef CONFIG_LIMITED_DMA
/*
* This is the same as kmap_atomic() but can map memory that doesn't
* have a struct page associated with it.
@@ -99,7 +98,6 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
return (void*) vaddr;
}
-#endif /* CONFIG_LIMITED_DMA */
struct page *__kmap_atomic_to_page(void *ptr)
{
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 2d1c2c02482..4c80528dead 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -424,9 +424,6 @@ void __init mem_init(void)
continue;
}
ClearPageReserved(page);
-#ifdef CONFIG_LIMITED_DMA
- set_page_address(page, lowmem_page_address(page));
-#endif
init_page_count(page);
__free_page(page);
totalhigh_pages++;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 492c518e7ba..e7149290d1c 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -35,24 +35,24 @@
#include <asm/smp.h>
#include <asm/war.h>
-static __init int __attribute__((unused)) r45k_bvahwbug(void)
+static __init int __maybe_unused r45k_bvahwbug(void)
{
/* XXX: We should probe for the presence of this bug, but we don't. */
return 0;
}
-static __init int __attribute__((unused)) r4k_250MHZhwbug(void)
+static __init int __maybe_unused r4k_250MHZhwbug(void)
{
/* XXX: We should probe for the presence of this bug, but we don't. */
return 0;
}
-static __init int __attribute__((unused)) bcm1250_m3_war(void)
+static __init int __maybe_unused bcm1250_m3_war(void)
{
return BCM1250_M3_WAR;
}
-static __init int __attribute__((unused)) r10000_llsc_war(void)
+static __init int __maybe_unused r10000_llsc_war(void)
{
return R10000_LLSC_WAR;
}
@@ -511,18 +511,18 @@ L_LA(_r3000_write_probe_fail)
#define i_ehb(buf) i_sll(buf, 0, 0, 3)
#ifdef CONFIG_64BIT
-static __init int __attribute__((unused)) in_compat_space_p(long addr)
+static __init int __maybe_unused in_compat_space_p(long addr)
{
/* Is this address in 32bit compat space? */
return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
}
-static __init int __attribute__((unused)) rel_highest(long val)
+static __init int __maybe_unused rel_highest(long val)
{
return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
}
-static __init int __attribute__((unused)) rel_higher(long val)
+static __init int __maybe_unused rel_higher(long val)
{
return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
}
@@ -556,8 +556,8 @@ static __init void i_LA_mostly(u32 **buf, unsigned int rs, long addr)
i_lui(buf, rs, rel_hi(addr));
}
-static __init void __attribute__((unused)) i_LA(u32 **buf, unsigned int rs,
- long addr)
+static __init void __maybe_unused i_LA(u32 **buf, unsigned int rs,
+ long addr)
{
i_LA_mostly(buf, rs, addr);
if (rel_lo(addr))
@@ -636,8 +636,8 @@ static __init void copy_handler(struct reloc *rel, struct label *lab,
move_labels(lab, first, end, off);
}
-static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel,
- u32 *addr)
+static __init int __maybe_unused insn_has_bdelay(struct reloc *rel,
+ u32 *addr)
{
for (; rel->lab != label_invalid; rel++) {
if (rel->addr == addr
@@ -650,15 +650,15 @@ static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel,
}
/* convenience functions for labeled branches */
-static void __init __attribute__((unused))
+static void __init __maybe_unused
il_bltz(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
{
r_mips_pc16(r, *p, l);
i_bltz(p, reg, 0);
}
-static void __init __attribute__((unused)) il_b(u32 **p, struct reloc **r,
- enum label_id l)
+static void __init __maybe_unused il_b(u32 **p, struct reloc **r,
+ enum label_id l)
{
r_mips_pc16(r, *p, l);
i_b(p, 0);
@@ -671,7 +671,7 @@ static void __init il_beqz(u32 **p, struct reloc **r, unsigned int reg,
i_beqz(p, reg, 0);
}
-static void __init __attribute__((unused))
+static void __init __maybe_unused
il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
{
r_mips_pc16(r, *p, l);
@@ -692,7 +692,7 @@ static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg,
i_bgezl(p, reg, 0);
}
-static void __init __attribute__((unused))
+static void __init __maybe_unused
il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
{
r_mips_pc16(r, *p, l);
@@ -810,7 +810,7 @@ static __initdata u32 final_handler[64];
*
* As if we MIPS hackers wouldn't know how to nop pipelines happy ...
*/
-static __init void __attribute__((unused)) build_tlb_probe_entry(u32 **p)
+static __init void __maybe_unused build_tlb_probe_entry(u32 **p)
{
switch (current_cpu_data.cputype) {
/* Found by experiment: R4600 v2.0 needs this, too. */
@@ -1098,7 +1098,7 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r,
* TMP and PTR are scratch.
* TMP will be clobbered, PTR will hold the pgd entry.
*/
-static __init void __attribute__((unused))
+static __init void __maybe_unused
build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
{
long pgdc = (long)pgd_current;
diff --git a/arch/mips/momentum/Kconfig b/arch/mips/momentum/Kconfig
deleted file mode 100644
index 70a61cf7174..00000000000
--- a/arch/mips/momentum/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config JAGUAR_DMALOW
- bool "Low DMA Mode"
- depends on MOMENCO_JAGUAR_ATX
- help
- Select to Y if jump JP5 is set on your board, N otherwise. Normally
- the jumper is set, so if you feel unsafe, just say Y.
diff --git a/arch/mips/momentum/jaguar_atx/Makefile b/arch/mips/momentum/jaguar_atx/Makefile
deleted file mode 100644
index 2e8cebd49bc..00000000000
--- a/arch/mips/momentum/jaguar_atx/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile for Momentum Computer's Jaguar-ATX board.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-obj-y += irq.o platform.o prom.o reset.o setup.o
-
-obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o
-obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff --git a/arch/mips/momentum/jaguar_atx/dbg_io.c b/arch/mips/momentum/jaguar_atx/dbg_io.c
deleted file mode 100644
index b85a6521f72..00000000000
--- a/arch/mips/momentum/jaguar_atx/dbg_io.c
+++ /dev/null
@@ -1,125 +0,0 @@
-
-#if defined(CONFIG_REMOTE_DEBUG)
-
-#include <asm/serial.h> /* For the serial port location and base baud */
-
-/* --- CONFIG --- */
-
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-
-/* --- END OF CONFIG --- */
-
-#define UART16550_BAUD_2400 2400
-#define UART16550_BAUD_4800 4800
-#define UART16550_BAUD_9600 9600
-#define UART16550_BAUD_19200 19200
-#define UART16550_BAUD_38400 38400
-#define UART16550_BAUD_57600 57600
-#define UART16550_BAUD_115200 115200
-
-#define UART16550_PARITY_NONE 0
-#define UART16550_PARITY_ODD 0x08
-#define UART16550_PARITY_EVEN 0x18
-#define UART16550_PARITY_MARK 0x28
-#define UART16550_PARITY_SPACE 0x38
-
-#define UART16550_DATA_5BIT 0x0
-#define UART16550_DATA_6BIT 0x1
-#define UART16550_DATA_7BIT 0x2
-#define UART16550_DATA_8BIT 0x3
-
-#define UART16550_STOP_1BIT 0x0
-#define UART16550_STOP_2BIT 0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [jsun] we use the second serial port for kdb */
-#define BASE OCELOT_SERIAL1_BASE
-#define MAX_BAUD OCELOT_BASE_BAUD
-
-/* === END OF CONFIG === */
-
-#define REG_OFFSET 4
-
-/* register offset */
-#define OFS_RCV_BUFFER 0
-#define OFS_TRANS_HOLD 0
-#define OFS_SEND_BUFFER 0
-#define OFS_INTR_ENABLE (1*REG_OFFSET)
-#define OFS_INTR_ID (2*REG_OFFSET)
-#define OFS_DATA_FORMAT (3*REG_OFFSET)
-#define OFS_LINE_CONTROL (3*REG_OFFSET)
-#define OFS_MODEM_CONTROL (4*REG_OFFSET)
-#define OFS_RS232_OUTPUT (4*REG_OFFSET)
-#define OFS_LINE_STATUS (5*REG_OFFSET)
-#define OFS_MODEM_STATUS (6*REG_OFFSET)
-#define OFS_RS232_INPUT (6*REG_OFFSET)
-#define OFS_SCRATCH_PAD (7*REG_OFFSET)
-
-#define OFS_DIVISOR_LSB (0*REG_OFFSET)
-#define OFS_DIVISOR_MSB (1*REG_OFFSET)
-
-
-/* memory-mapped read/write of the port */
-#define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
-#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
- /* disable interrupts */
- UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
- /* set up baud rate */
- {
- uint32 divisor;
-
- /* set DIAB bit */
- UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
- /* set divisor */
- divisor = MAX_BAUD / baud;
- UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
- UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
- /* clear DIAB bit */
- UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
- }
-
- /* set data format */
- UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
- if (!remoteDebugInitialized) {
- remoteDebugInitialized = 1;
- debugInit(UART16550_BAUD_38400,
- UART16550_DATA_8BIT,
- UART16550_PARITY_NONE, UART16550_STOP_1BIT);
- }
-
- while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
- return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-
-int putDebugChar(uint8 byte)
-{
- if (!remoteDebugInitialized) {
- remoteDebugInitialized = 1;
- debugInit(UART16550_BAUD_38400,
- UART16550_DATA_8BIT,
- UART16550_PARITY_NONE, UART16550_STOP_1BIT);
- }
-
- while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
- UART16550_WRITE(OFS_SEND_BUFFER, byte);
- return 1;
-}
-
-#endif
diff --git a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c
deleted file mode 100644
index f2b432585df..00000000000
--- a/arch/mips/momentum/jaguar_atx/irq.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2002 Momentum Computer, Inc.
- * Author: Matthew Dharm, mdharm@momenco.com
- *
- * Based on work by:
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- *
- * Copyright (C) 2000, 01, 06 Ralf Baechle (ralf@linux-mips.org)
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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 <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/signal.h>
-#include <linux/types.h>
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/time.h>
-
-asmlinkage void plat_irq_dispatch(void)
-{
- unsigned int pending = read_c0_cause() & read_c0_status();
-
- if (pending & STATUSF_IP0)
- do_IRQ(0);
- else if (pending & STATUSF_IP1)
- do_IRQ(1);
- else if (pending & STATUSF_IP2)
- do_IRQ(2);
- else if (pending & STATUSF_IP3)
- do_IRQ(3);
- else if (pending & STATUSF_IP4)
- do_IRQ(4);
- else if (pending & STATUSF_IP5)
- do_IRQ(5);
- else if (pending & STATUSF_IP6)
- do_IRQ(6);
- else if (pending & STATUSF_IP7)
- ll_timer_interrupt(7);
- else {
- /*
- * Now look at the extended interrupts
- */
- pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
- if (pending & STATUSF_IP8)
- ll_mv64340_irq();
- }
-}
-
-static struct irqaction cascade_mv64340 = {
- no_action, IRQF_DISABLED, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
-};
-
-void __init arch_init_irq(void)
-{
- /*
- * Clear all of the interrupts while we change the able around a bit.
- * int-handler is not on bootstrap
- */
- clear_c0_status(ST0_IM);
-
- mips_cpu_irq_init();
- rm7k_cpu_irq_init();
-
- /* set up the cascading interrupts */
- setup_irq(8, &cascade_mv64340);
-
- mv64340_irq_init(16);
-
- set_c0_status(ST0_IM);
-}
diff --git a/arch/mips/momentum/jaguar_atx/ja-console.c b/arch/mips/momentum/jaguar_atx/ja-console.c
deleted file mode 100644
index 2c30b4f5624..00000000000
--- a/arch/mips/momentum/jaguar_atx/ja-console.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2001, 2002, 2004 Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/major.h>
-#include <linux/termios.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <asm/serial.h>
-
-/* SUPERIO uart register map */
-struct ja_uartregs {
- union {
- volatile u8 pad0[3];
- volatile u8 rbr; /* read only, DLAB == 0 */
- volatile u8 pad1[3];
- volatile u8 thr; /* write only, DLAB == 0 */
- volatile u8 pad2[3];
- volatile u8 dll; /* DLAB == 1 */
- } u1;
- union {
- volatile u8 pad0[3];
- volatile u8 ier; /* DLAB == 0 */
- volatile u8 pad1[3];
- volatile u8 dlm; /* DLAB == 1 */
- } u2;
- union {
- volatile u8 pad0[3];
- volatile u8 iir; /* read only */
- volatile u8 pad1[3];
- volatile u8 fcr; /* write only */
- } u3;
- volatile u8 pad0[3];
- volatile u8 iu_lcr;
- volatile u8 pad1[3];
- volatile u8 iu_mcr;
- volatile u8 pad2[3];
- volatile u8 iu_lsr;
- volatile u8 pad3[3];
- volatile u8 iu_msr;
- volatile u8 pad4[3];
- volatile u8 iu_scr;
-} ja_uregs_t;
-
-#define iu_rbr u1.rbr
-#define iu_thr u1.thr
-#define iu_dll u1.dll
-#define iu_ier u2.ier
-#define iu_dlm u2.dlm
-#define iu_iir u3.iir
-#define iu_fcr u3.fcr
-
-extern unsigned long uart_base;
-
-static inline struct ja_uartregs *console_uart(void)
-{
- return (struct ja_uartregs *) (uart_base + 0x23UL);
-}
-
-void prom_putchar(char c)
-{
- struct ja_uartregs *uart = console_uart();
-
- while ((uart->iu_lsr & 0x20) == 0);
- uart->iu_thr = c;
-}
-
-static void inline ja_console_probe(void)
-{
- struct uart_port up;
-
- /*
- * Register to interrupt zero because we share the interrupt with
- * the serial driver which we don't properly support yet.
- */
- memset(&up, 0, sizeof(up));
- up.membase = (unsigned char *) uart_base + 0x23UL;
- up.irq = JAGUAR_ATX_SERIAL1_IRQ;
- up.uartclk = JAGUAR_ATX_UART_CLK;
- up.regshift = 2;
- up.iotype = UPIO_MEM;
- up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
- up.line = 0;
-
- if (early_serial_setup(&up))
- printk(KERN_ERR "Early serial init of port 0 failed\n");
-}
-
-__init void ja_setup_console(void)
-{
- ja_console_probe();
-}
diff --git a/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h b/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h
deleted file mode 100644
index 022f6974b76..00000000000
--- a/arch/mips/momentum/jaguar_atx/jaguar_atx_fpga.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Jaguar-ATX Board Register Definitions
- *
- * (C) 2002 Momentum Computer Inc.
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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.
- */
-#ifndef __JAGUAR_ATX_FPGA_H__
-#define __JAGUAR_ATX_FPGA_H__
-
-#define JAGUAR_ATX_REG_BOARDREV 0x0
-#define JAGUAR_ATX_REG_FPGA_REV 0x1
-#define JAGUAR_ATX_REG_FPGA_TYPE 0x2
-#define JAGUAR_ATX_REG_RESET_STATUS 0x3
-#define JAGUAR_ATX_REG_BOARD_STATUS 0x4
-#define JAGUAR_ATX_REG_RESERVED1 0x5
-#define JAGUAR_ATX_REG_SET 0x6
-#define JAGUAR_ATX_REG_CLR 0x7
-#define JAGUAR_ATX_REG_EEPROM_MODE 0x9
-#define JAGUAR_ATX_REG_RESERVED2 0xa
-#define JAGUAR_ATX_REG_RESERVED3 0xb
-#define JAGUAR_ATX_REG_RESERVED4 0xc
-#define JAGUAR_ATX_REG_PHY_INTSTAT 0xd
-#define JAGUAR_ATX_REG_RESERVED5 0xe
-#define JAGUAR_ATX_REG_RESERVED6 0xf
-
-#define JAGUAR_ATX_CS0_ADDR 0xfc000000L
-
-extern unsigned long ja_fpga_base;
-
-#define __FPGA_REG_TO_ADDR(reg) \
- ((void *) ja_fpga_base + JAGUAR_ATX_REG_##reg)
-#define JAGUAR_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg))
-#define JAGUAR_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg))
-
-#endif
diff --git a/arch/mips/momentum/jaguar_atx/platform.c b/arch/mips/momentum/jaguar_atx/platform.c
deleted file mode 100644
index 561844878a9..00000000000
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ /dev/null
@@ -1,208 +0,0 @@
-#include <linux/delay.h>
-#include <linux/if_ether.h>
-#include <linux/ioport.h>
-#include <linux/mv643xx.h>
-#include <linux/platform_device.h>
-
-#include "jaguar_atx_fpga.h"
-
-#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE)
-
-static struct resource mv643xx_eth_shared_resources[] = {
- [0] = {
- .name = "ethernet shared base",
- .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
- .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
- MV643XX_ETH_SHARED_REGS_SIZE - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device mv643xx_eth_shared_device = {
- .name = MV643XX_ETH_SHARED_NAME,
- .id = 0,
- .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
- .resource = mv643xx_eth_shared_resources,
-};
-
-#define MV_SRAM_BASE 0xfe000000UL
-#define MV_SRAM_SIZE (256 * 1024)
-
-#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4)
-#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4)
-
-#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE
-#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2))
-
-#define MV64x60_IRQ_ETH_0 48
-#define MV64x60_IRQ_ETH_1 49
-#define MV64x60_IRQ_ETH_2 50
-
-static struct resource mv64x60_eth0_resources[] = {
- [0] = {
- .name = "eth0 irq",
- .start = MV64x60_IRQ_ETH_0,
- .end = MV64x60_IRQ_ETH_0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct mv643xx_eth_platform_data eth0_pd = {
- .port_number = 0,
-
- .tx_sram_addr = MV_SRAM_BASE_ETH0,
- .tx_sram_size = MV_SRAM_TXRING_SIZE,
- .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
-
- .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE,
- .rx_sram_size = MV_SRAM_RXRING_SIZE,
- .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
-};
-
-static struct platform_device eth0_device = {
- .name = MV643XX_ETH_NAME,
- .id = 0,
- .num_resources = ARRAY_SIZE(mv64x60_eth0_resources),
- .resource = mv64x60_eth0_resources,
- .dev = {
- .platform_data = &eth0_pd,
- },
-};
-
-static struct resource mv64x60_eth1_resources[] = {
- [0] = {
- .name = "eth1 irq",
- .start = MV64x60_IRQ_ETH_1,
- .end = MV64x60_IRQ_ETH_1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct mv643xx_eth_platform_data eth1_pd = {
- .port_number = 1,
-
- .tx_sram_addr = MV_SRAM_BASE_ETH1,
- .tx_sram_size = MV_SRAM_TXRING_SIZE,
- .tx_queue_size = MV_SRAM_TXRING_SIZE / 16,
-
- .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE,
- .rx_sram_size = MV_SRAM_RXRING_SIZE,
- .rx_queue_size = MV_SRAM_RXRING_SIZE / 16,
-};
-
-static struct platform_device eth1_device = {
- .name = MV643XX_ETH_NAME,
- .id = 1,
- .num_resources = ARRAY_SIZE(mv64x60_eth1_resources),
- .resource = mv64x60_eth1_resources,
- .dev = {
- .platform_data = &eth1_pd,
- },
-};
-
-static struct resource mv64x60_eth2_resources[] = {
- [0] = {
- .name = "eth2 irq",
- .start = MV64x60_IRQ_ETH_2,
- .end = MV64x60_IRQ_ETH_2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct mv643xx_eth_platform_data eth2_pd = {
- .port_number = 2,
-};
-
-static struct platform_device eth2_device = {
- .name = MV643XX_ETH_NAME,
- .id = 2,
- .num_resources = ARRAY_SIZE(mv64x60_eth2_resources),
- .resource = mv64x60_eth2_resources,
- .dev = {
- .platform_data = &eth2_pd,
- },
-};
-
-static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
- &mv643xx_eth_shared_device,
- &eth0_device,
- &eth1_device,
- &eth2_device,
-};
-
-static u8 __init exchange_bit(u8 val, u8 cs)
-{
- /* place the data */
- JAGUAR_FPGA_WRITE((val << 2) | cs, EEPROM_MODE);
- udelay(1);
-
- /* turn the clock on */
- JAGUAR_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE);
- udelay(1);
-
- /* turn the clock off and read-strobe */
- JAGUAR_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE);
-
- /* return the data */
- return (JAGUAR_FPGA_READ(EEPROM_MODE) >> 3) & 0x1;
-}
-
-static void __init get_mac(char dest[6])
-{
- u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i,j;
-
- for (i = 0; i < 12; i++)
- exchange_bit(read_opcode[i], 1);
-
- for (j = 0; j < 6; j++) {
- dest[j] = 0;
- for (i = 0; i < 8; i++) {
- dest[j] <<= 1;
- dest[j] |= exchange_bit(0, 1);
- }
- }
-
- /* turn off CS */
- exchange_bit(0,0);
-}
-
-/*
- * Copy and increment ethernet MAC address by a small value.
- *
- * This is useful for systems where the only one MAC address is stored in
- * non-volatile memory for multiple ports.
- */
-static inline void eth_mac_add(unsigned char *dst, unsigned char *src,
- unsigned int add)
-{
- int i;
-
- BUG_ON(add >= 256);
-
- for (i = ETH_ALEN; i >= 0; i--) {
- dst[i] = src[i] + add;
- add = dst[i] < src[i]; /* compute carry */
- }
-
- WARN_ON(add);
-}
-
-static int __init mv643xx_eth_add_pds(void)
-{
- unsigned char mac[ETH_ALEN];
- int ret;
-
- get_mac(mac);
- eth_mac_add(eth0_pd.mac_addr, mac, 0);
- eth_mac_add(eth1_pd.mac_addr, mac, 1);
- eth_mac_add(eth2_pd.mac_addr, mac, 2);
- ret = platform_add_devices(mv643xx_eth_pd_devs,
- ARRAY_SIZE(mv643xx_eth_pd_devs));
-
- return ret;
-}
-
-device_initcall(mv643xx_eth_add_pds);
-
-#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */
diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c
deleted file mode 100644
index 5dd154ee58f..00000000000
--- a/arch/mips/momentum/jaguar_atx/prom.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Louis Hamilton, Red Hat, Inc.
- * hamilton@redhat.com [MIPS64 modifications]
- *
- * Based on Ocelot Linux port, which is
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * 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.
- *
- * Added changes for SMP - Manish Lachwani (lachwani@pmc-sierra.com)
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <linux/mv643xx.h>
-
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <asm/pmon.h>
-
-#include "jaguar_atx_fpga.h"
-
-extern void ja_setup_console(void);
-
-struct callvectors *debug_vectors;
-
-extern unsigned long cpu_clock;
-
-const char *get_system_type(void)
-{
- return "Momentum Jaguar-ATX";
-}
-
-#ifdef CONFIG_64BIT
-
-unsigned long signext(unsigned long addr)
-{
- addr &= 0xffffffff;
- return (unsigned long)((int)addr);
-}
-
-void *get_arg(unsigned long args, int arc)
-{
- unsigned long ul;
- unsigned char *puc, uc;
-
- args += (arc * 4);
- ul = (unsigned long)signext(args);
- puc = (unsigned char *)ul;
- if (puc == 0)
- return (void *)0;
-
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
- uc = *puc++;
- l = (unsigned long)uc;
- uc = *puc++;
- ul |= (((unsigned long)uc) << 8);
- uc = *puc++;
- ul |= (((unsigned long)uc) << 16);
- uc = *puc++;
- ul |= (((unsigned long)uc) << 24);
-#else
- uc = *puc++;
- ul = ((unsigned long)uc) << 24;
- uc = *puc++;
- ul |= (((unsigned long)uc) << 16);
- uc = *puc++;
- ul |= (((unsigned long)uc) << 8);
- uc = *puc++;
- ul |= ((unsigned long)uc);
-#endif
- ul = signext(ul);
-
- return (void *)ul;
-}
-
-char *arg64(unsigned long addrin, int arg_index)
-{
- unsigned long args;
- char *p;
-
- args = signext(addrin);
- p = (char *)get_arg(args, arg_index);
-
- return p;
-}
-#endif /* CONFIG_64BIT */
-
-/* PMON passes arguments in C main() style */
-void __init prom_init(void)
-{
- int argc = fw_arg0;
- char **arg = (char **) fw_arg1;
- char **env = (char **) fw_arg2;
- struct callvectors *cv = (struct callvectors *) fw_arg3;
- int i;
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-// ja_setup_console(); /* The very first thing. */
-#endif
-
-#ifdef CONFIG_64BIT
- char *ptr;
-
- printk("Mips64 Jaguar-ATX\n");
- /* save the PROM vectors for debugging use */
- debug_vectors = (struct callvectors *)signext((unsigned long)cv);
-
- /* arg[0] is "g", the rest is boot parameters */
- arcs_cmdline[0] = '\0';
-
- for (i = 1; i < argc; i++) {
- ptr = (char *)arg64((unsigned long)arg, i);
- if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
- sizeof(arcs_cmdline))
- break;
- strcat(arcs_cmdline, ptr);
- strcat(arcs_cmdline, " ");
- }
-
- i = 0;
- while (1) {
- ptr = (char *)arg64((unsigned long)env, i);
- if (! ptr)
- break;
-
- if (strncmp("gtbase", ptr, strlen("gtbase")) == 0) {
- marvell_base = simple_strtol(ptr + strlen("gtbase="),
- NULL, 16);
-
- if ((marvell_base & 0xffffffff00000000) == 0)
- marvell_base |= 0xffffffff00000000;
-
- printk("marvell_base set to 0x%016lx\n", marvell_base);
- }
- if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
- cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
- NULL, 10);
- printk("cpu_clock set to %d\n", cpu_clock);
- }
- i++;
- }
- printk("arcs_cmdline: %s\n", arcs_cmdline);
-
-#else /* CONFIG_64BIT */
- /* save the PROM vectors for debugging use */
- debug_vectors = cv;
-
- /* arg[0] is "g", the rest is boot parameters */
- arcs_cmdline[0] = '\0';
- for (i = 1; i < argc; i++) {
- if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
- >= sizeof(arcs_cmdline))
- break;
- strcat(arcs_cmdline, arg[i]);
- strcat(arcs_cmdline, " ");
- }
-
- while (*env) {
- if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
- marvell_base = simple_strtol(*env + strlen("gtbase="),
- NULL, 16);
- }
- if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
- cpu_clock = simple_strtol(*env + strlen("cpuclock="),
- NULL, 10);
- }
- env++;
- }
-#endif /* CONFIG_64BIT */
- mips_machgroup = MACH_GROUP_MOMENCO;
- mips_machtype = MACH_MOMENCO_JAGUAR_ATX;
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
-{
-}
-
-int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
-{
- /* Clear the semaphore */
- *(volatile uint32_t *)(0xbb000a68) = 0x80000000;
-
- return 1;
-}
-
-void prom_init_secondary(void)
-{
- clear_c0_config(CONF_CM_CMASK);
- set_c0_config(0x2);
-
- clear_c0_status(ST0_IM);
- set_c0_status(0x1ffff);
-}
-
-void prom_smp_finish(void)
-{
-}
diff --git a/arch/mips/momentum/jaguar_atx/reset.c b/arch/mips/momentum/jaguar_atx/reset.c
deleted file mode 100644
index c73b0897dc5..00000000000
--- a/arch/mips/momentum/jaguar_atx/reset.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 1997, 2001 Ralf Baechle
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * Copyright (C) 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Louis Hamilton, Red Hat, Inc.
- * hamilton@redhat.com [MIPS64 modifications]
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-#include <linux/delay.h>
-
-void momenco_jaguar_restart(char *command)
-{
- /* base address of timekeeper portion of part */
-#ifdef CONFIG_64BIT
- void *nvram = (void*) 0xfffffffffc807000;
-#else
- void *nvram = (void*) 0xfc807000;
-#endif
- /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
- writeb(0x84, nvram + 0xff7);
-
- /* wait for the watchdog to go off */
- mdelay(100+(1000/16));
-
- /* if the watchdog fails for some reason, let people know */
- printk(KERN_NOTICE "Watchdog reset failed\n");
-}
-
-void momenco_jaguar_halt(void)
-{
- printk(KERN_NOTICE "\n** You can safely turn off the power\n");
- while (1)
- __asm__(".set\tmips3\n\t"
- "wait\n\t"
- ".set\tmips0");
-}
-
-void momenco_jaguar_power_off(void)
-{
- momenco_jaguar_halt();
-}
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
deleted file mode 100644
index 5a510142b97..00000000000
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Momentum Computer Jaguar-ATX board dependent boot routines
- *
- * Copyright (C) 1996, 1997, 2001, 04, 06 Ralf Baechle (ralf@linux-mips.org)
- * Copyright (C) 2000 RidgeRun, Inc.
- * Copyright (C) 2001 Red Hat, Inc.
- * Copyright (C) 2002 Momentum Computer
- *
- * Author: Matthew Dharm, Momentum Computer
- * mdharm@momenco.com
- *
- * Louis Hamilton, Red Hat, Inc.
- * hamilton@redhat.com [MIPS64 modifications]
- *
- * Author: RidgeRun, Inc.
- * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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 <linux/bcd.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/swap.h>
-#include <linux/ioport.h>
-#include <linux/pm.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/vmalloc.h>
-#include <linux/mv643xx.h>
-
-#include <asm/time.h>
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/tlbflush.h>
-
-#include "jaguar_atx_fpga.h"
-
-extern unsigned long mv64340_sram_base;
-unsigned long cpu_clock;
-
-/* These functions are used for rebooting or halting the machine*/
-extern void momenco_jaguar_restart(char *command);
-extern void momenco_jaguar_halt(void);
-extern void momenco_jaguar_power_off(void);
-
-void momenco_time_init(void);
-
-static char reset_reason;
-
-static inline unsigned long ENTRYLO(unsigned long paddr)
-{
- return ((paddr & PAGE_MASK) |
- (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
- _CACHE_UNCACHED)) >> 6;
-}
-
-void __init bus_error_init(void) { /* nothing */ }
-
-/*
- * Load a few TLB entries for the MV64340 and perhiperals. The MV64340 is going
- * to be hit on every IRQ anyway - there's absolutely no point in letting it be
- * a random TLB entry, as it'll just cause needless churning of the TLB. And we
- * use the other half for the serial port, which is just a PITA otherwise :)
- *
- * Device Physical Virtual
- * MV64340 Internal Regs 0xf4000000 0xf4000000
- * Ocelot-C[S] PLD (CS0) 0xfc000000 0xfc000000
- * NVRAM (CS1) 0xfc800000 0xfc800000
- * UARTs (CS2) 0xfd000000 0xfd000000
- * Internal SRAM 0xfe000000 0xfe000000
- * M-Systems DOC (CS3) 0xff000000 0xff000000
- */
-
-static __init void wire_stupidity_into_tlb(void)
-{
-#ifdef CONFIG_32BIT
- write_c0_wired(0);
- local_flush_tlb_all();
-
- /* marvell and extra space */
- add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000),
- 0xf4000000UL, PM_64K);
- /* fpga, rtc, and uart */
- add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000),
- 0xfc000000UL, PM_16M);
-// /* m-sys and internal SRAM */
-// add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000),
-// 0xfe000000UL, PM_16M);
-
- marvell_base = 0xf4000000;
- //mv64340_sram_base = 0xfe000000; /* Currently unused */
-#endif
-}
-
-unsigned long marvell_base = 0xf4000000L;
-unsigned long ja_fpga_base = JAGUAR_ATX_CS0_ADDR;
-unsigned long uart_base = 0xfd000000L;
-static unsigned char *rtc_base = (unsigned char*) 0xfc800000L;
-
-EXPORT_SYMBOL(marvell_base);
-
-static __init int per_cpu_mappings(void)
-{
- marvell_base = (unsigned long) ioremap(0xf4000000, 0x10000);
- ja_fpga_base = (unsigned long) ioremap(JAGUAR_ATX_CS0_ADDR, 0x1000);
- uart_base = (unsigned long) ioremap(0xfd000000UL, 0x1000);
- rtc_base = ioremap(0xfc000000UL, 0x8000);
- // ioremap(0xfe000000, 32 << 20);
- write_c0_wired(0);
- local_flush_tlb_all();
- ja_setup_console();
-
- return 0;
-}
-arch_initcall(per_cpu_mappings);
-
-unsigned long m48t37y_get_time(void)
-{
- unsigned int year, month, day, hour, min, sec;
- unsigned long flags;
-
- spin_lock_irqsave(&rtc_lock, flags);
- /* stop the update */
- rtc_base[0x7ff8] = 0x40;
-
- year = BCD2BIN(rtc_base[0x7fff]);
- year += BCD2BIN(rtc_base[0x7ff1]) * 100;
-
- month = BCD2BIN(rtc_base[0x7ffe]);
-
- day = BCD2BIN(rtc_base[0x7ffd]);
-
- hour = BCD2BIN(rtc_base[0x7ffb]);
- min = BCD2BIN(rtc_base[0x7ffa]);
- sec = BCD2BIN(rtc_base[0x7ff9]);
-
- /* start the update */
- rtc_base[0x7ff8] = 0x00;
- spin_unlock_irqrestore(&rtc_lock, flags);
-
- return mktime(year, month, day, hour, min, sec);
-}
-
-int m48t37y_set_time(unsigned long sec)
-{
- struct rtc_time tm;
- unsigned long flags;
-
- /* convert to a more useful format -- note months count from 0 */
- to_tm(sec, &tm);
- tm.tm_mon += 1;
-
- spin_lock_irqsave(&rtc_lock, flags);
- /* enable writing */
- rtc_base[0x7ff8] = 0x80;
-
- /* year */
- rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
- rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
-
- /* month */
- rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
-
- /* day */
- rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
-
- /* hour/min/sec */
- rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
- rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
- rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
-
- /* day of week -- not really used, but let's keep it up-to-date */
- rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
-
- /* disable writing */
- rtc_base[0x7ff8] = 0x00;
- spin_unlock_irqrestore(&rtc_lock, flags);
-
- return 0;
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
- setup_irq(8, irq);
-}
-
-/*
- * Ugly but the least of all evils. TLB initialization did flush the TLB so
- * We need to setup mappings again before we can touch the RTC.
- */
-void momenco_time_init(void)
-{
- wire_stupidity_into_tlb();
-
- mips_hpt_frequency = cpu_clock / 2;
-
- rtc_mips_get_time = m48t37y_get_time;
- rtc_mips_set_time = m48t37y_set_time;
-}
-
-static struct resource mv_pci_io_mem0_resource = {
- .name = "MV64340 PCI0 IO MEM",
- .flags = IORESOURCE_IO
-};
-
-static struct resource mv_pci_mem0_resource = {
- .name = "MV64340 PCI0 MEM",
- .flags = IORESOURCE_MEM
-};
-
-static struct mv_pci_controller mv_bus0_controller = {
- .pcic = {
- .pci_ops = &mv_pci_ops,
- .mem_resource = &mv_pci_mem0_resource,
- .io_resource = &mv_pci_io_mem0_resource,
- },
- .config_addr = MV64340_PCI_0_CONFIG_ADDR,
- .config_vreg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
-};
-
-static uint32_t mv_io_base, mv_io_size;
-
-static void ja_pci0_init(void)
-{
- uint32_t mem0_base, mem0_size;
- uint32_t io_base, io_size;
-
- io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
- io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
- mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
- mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
-
- mv_pci_io_mem0_resource.start = 0;
- mv_pci_io_mem0_resource.end = io_size - 1;
- mv_pci_mem0_resource.start = mem0_base;
- mv_pci_mem0_resource.end = mem0_base + mem0_size - 1;
- mv_bus0_controller.pcic.mem_offset = mem0_base;
- mv_bus0_controller.pcic.io_offset = 0;
-
- ioport_resource.end = io_size - 1;
-
- register_pci_controller(&mv_bus0_controller.pcic);
-
- mv_io_base = io_base;
- mv_io_size = io_size;
-}
-
-static struct resource mv_pci_io_mem1_resource = {
- .name = "MV64340 PCI1 IO MEM",
- .flags = IORESOURCE_IO
-};
-
-static struct resource mv_pci_mem1_resource = {
- .name = "MV64340 PCI1 MEM",
- .flags = IORESOURCE_MEM
-};
-
-static struct mv_pci_controller mv_bus1_controller = {
- .pcic = {
- .pci_ops = &mv_pci_ops,
- .mem_resource = &mv_pci_mem1_resource,
- .io_resource = &mv_pci_io_mem1_resource,
- },
- .config_addr = MV64340_PCI_1_CONFIG_ADDR,
- .config_vreg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
-};
-
-static __init void ja_pci1_init(void)
-{
- uint32_t mem0_base, mem0_size;
- uint32_t io_base, io_size;
-
- io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
- io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
- mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
- mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
-
- /*
- * Here we assume the I/O window of second bus to be contiguous with
- * the first. A gap is no problem but would waste address space for
- * remapping the port space.
- */
- mv_pci_io_mem1_resource.start = mv_io_size;
- mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1;
- mv_pci_mem1_resource.start = mem0_base;
- mv_pci_mem1_resource.end = mem0_base + mem0_size - 1;
- mv_bus1_controller.pcic.mem_offset = mem0_base;
- mv_bus1_controller.pcic.io_offset = 0;
-
- ioport_resource.end = io_base + io_size -mv_io_base - 1;
-
- register_pci_controller(&mv_bus1_controller.pcic);
-
- mv_io_size = io_base + io_size - mv_io_base;
-}
-
-static __init int __init ja_pci_init(void)
-{
- unsigned long io_v_base;
- uint32_t enable;
-
- enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
-
- /*
- * We require at least one enabled I/O or PCI memory window or we
- * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3.
- */
- if (enable & (0x01 << 9) || enable & (0x01 << 10))
- ja_pci0_init();
-
- if (enable & (0x01 << 14) || enable & (0x01 << 15))
- ja_pci1_init();
-
- if (mv_io_size) {
- io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
- if (!io_v_base)
- panic("Could not ioremap I/O port range");
-
- set_io_port_base(io_v_base);
- }
-
- return 0;
-}
-
-arch_initcall(ja_pci_init);
-
-void __init plat_mem_setup(void)
-{
- unsigned int tmpword;
-
- board_time_init = momenco_time_init;
-
- _machine_restart = momenco_jaguar_restart;
- _machine_halt = momenco_jaguar_halt;
- pm_power_off = momenco_jaguar_power_off;
-
- /*
- * initrd_start = (unsigned long)jaguar_initrd_start;
- * initrd_end = (unsigned long)jaguar_initrd_start + (ulong)jaguar_initrd_size;
- * initrd_below_start_ok = 1;
- */
-
- wire_stupidity_into_tlb();
-
- /*
- * shut down ethernet ports, just to be sure our memory doesn't get
- * corrupted by random ethernet traffic.
- */
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
- MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8);
- MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
- MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
- MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8);
- while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
- while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
- while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff);
- while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
- while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
- while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff);
- MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
- MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
- MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
- MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
- MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2),
- MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1);
-
- /* Turn off the Bit-Error LED */
- JAGUAR_FPGA_WRITE(0x80, CLR);
-
- tmpword = JAGUAR_FPGA_READ(BOARDREV);
- if (tmpword < 26)
- printk("Momentum Jaguar-ATX: Board Assembly Rev. %c\n",
- 'A'+tmpword);
- else
- printk("Momentum Jaguar-ATX: Board Assembly Revision #0x%x\n",
- tmpword);
-
- tmpword = JAGUAR_FPGA_READ(FPGA_REV);
- printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
- tmpword = JAGUAR_FPGA_READ(RESET_STATUS);
- printk("Reset reason: 0x%x\n", tmpword);
- switch (tmpword) {
- case 0x1:
- printk(" - Power-up reset\n");
- break;
- case 0x2:
- printk(" - Push-button reset\n");
- break;
- case 0x8:
- printk(" - Watchdog reset\n");
- break;
- case 0x10:
- printk(" - JTAG reset\n");
- break;
- default:
- printk(" - Unknown reset cause\n");
- }
- reset_reason = tmpword;
- JAGUAR_FPGA_WRITE(0xff, RESET_STATUS);
-
- tmpword = JAGUAR_FPGA_READ(BOARD_STATUS);
- printk("Board Status register: 0x%02x\n", tmpword);
- printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
- printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
-
- /* 256MiB of RM9000x2 DDR */
-// add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM);
-
- /* 128MiB of MV-64340 DDR */
-// add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM);
-
- /* XXX Memory configuration should be picked up from PMON2k */
-#ifdef CONFIG_JAGUAR_DMALOW
- printk("Jaguar ATX DMA-low mode set\n");
- add_memory_region(0x00000000, 0x08000000, BOOT_MEM_RAM);
- add_memory_region(0x08000000, 0x10000000, BOOT_MEM_RAM);
-#else
- /* 128MiB of MV-64340 DDR RAM */
- printk("Jaguar ATX DMA-low mode is not set\n");
- add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM);
-#endif
-
-#ifdef GEMDEBUG_TRACEBUFFER
- {
- unsigned int tbControl;
- tbControl =
- 0 << 26 | /* post trigger delay 0 */
- 0x2 << 16 | /* sequential trace mode */
- // 0x0 << 16 | /* non-sequential trace mode */
- // 0xf << 4 | /* watchpoints disabled */
- 2 << 2 | /* armed */
- 2 ; /* interrupt disabled */
- printk ("setting tbControl = %08lx\n", tbControl);
- write_32bit_cp0_set1_register($22, tbControl);
- __asm__ __volatile__(".set noreorder\n\t" \
- "nop; nop; nop; nop; nop; nop;\n\t" \
- "nop; nop; nop; nop; nop; nop;\n\t" \
- ".set reorder\n\t");
-
- }
-#endif
-}
diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile
deleted file mode 100644
index c0a0030d949..00000000000
--- a/arch/mips/momentum/ocelot_g/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Makefile for Momentum Computer's Ocelot-G board.
-#
-
-obj-y += irq.o gt-irq.o prom.o reset.o setup.o
-obj-$(CONFIG_KGDB) += dbg_io.o
diff --git a/arch/mips/momentum/ocelot_g/dbg_io.c b/arch/mips/momentum/ocelot_g/dbg_io.c
deleted file mode 100644
index 32d6fb4ee67..00000000000
--- a/arch/mips/momentum/ocelot_g/dbg_io.c
+++ /dev/null
@@ -1,121 +0,0 @@
-
-#include <asm/serial.h> /* For the serial port location and base baud */
-
-/* --- CONFIG --- */
-
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-
-/* --- END OF CONFIG --- */
-
-#define UART16550_BAUD_2400 2400
-#define UART16550_BAUD_4800 4800
-#define UART16550_BAUD_9600 9600
-#define UART16550_BAUD_19200 19200
-#define UART16550_BAUD_38400 38400
-#define UART16550_BAUD_57600 57600
-#define UART16550_BAUD_115200 115200
-
-#define UART16550_PARITY_NONE 0
-#define UART16550_PARITY_ODD 0x08
-#define UART16550_PARITY_EVEN 0x18
-#define UART16550_PARITY_MARK 0x28
-#define UART16550_PARITY_SPACE 0x38
-
-#define UART16550_DATA_5BIT 0x0
-#define UART16550_DATA_6BIT 0x1
-#define UART16550_DATA_7BIT 0x2
-#define UART16550_DATA_8BIT 0x3
-
-#define UART16550_STOP_1BIT 0x0
-#define UART16550_STOP_2BIT 0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [jsun] we use the second serial port for kdb */
-#define BASE OCELOT_SERIAL1_BASE
-#define MAX_BAUD OCELOT_BASE_BAUD
-
-/* === END OF CONFIG === */
-
-#define REG_OFFSET 4
-
-/* register offset */
-#define OFS_RCV_BUFFER 0
-#define OFS_TRANS_HOLD 0
-#define OFS_SEND_BUFFER 0
-#define OFS_INTR_ENABLE (1*REG_OFFSET)
-#define OFS_INTR_ID (2*REG_OFFSET)
-#define OFS_DATA_FORMAT (3*REG_OFFSET)
-#define OFS_LINE_CONTROL (3*REG_OFFSET)
-#define OFS_MODEM_CONTROL (4*REG_OFFSET)
-#define OFS_RS232_OUTPUT (4*REG_OFFSET)
-#define OFS_LINE_STATUS (5*REG_OFFSET)
-#define OFS_MODEM_STATUS (6*REG_OFFSET)
-#define OFS_RS232_INPUT (6*REG_OFFSET)
-#define OFS_SCRATCH_PAD (7*REG_OFFSET)
-
-#define OFS_DIVISOR_LSB (0*REG_OFFSET)
-#define OFS_DIVISOR_MSB (1*REG_OFFSET)
-
-
-/* memory-mapped read/write of the port */
-#define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
-#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
- /* disable interrupts */
- UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
- /* set up baud rate */
- {
- uint32 divisor;
-
- /* set DIAB bit */
- UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
- /* set divisor */
- divisor = MAX_BAUD / baud;
- UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
- UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
- /* clear DIAB bit */
- UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
- }
-
- /* set data format */
- UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
- if (!remoteDebugInitialized) {
- remoteDebugInitialized = 1;
- debugInit(UART16550_BAUD_38400,
- UART16550_DATA_8BIT,
- UART16550_PARITY_NONE, UART16550_STOP_1BIT);
- }
-
- while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
- return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-
-int putDebugChar(uint8 byte)
-{
- if (!remoteDebugInitialized) {
- remoteDebugInitialized = 1;
- debugInit(UART16550_BAUD_38400,
- UART16550_DATA_8BIT,
- UART16550_PARITY_NONE, UART16550_STOP_1BIT);
- }
-
- while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
- UART16550_WRITE(OFS_SEND_BUFFER, byte);
- return 1;
-}
diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c
deleted file mode 100644
index e5576bd50fa..00000000000
--- a/arch/mips/momentum/ocelot_g/gt-irq.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *
- * Copyright 2002 Momentum Computer
- * Author: mdharm@momenco.com
- *
- * arch/mips/momentum/ocelot_g/gt_irq.c
- * Interrupt routines for gt64240. Currently it only handles timer irq.
- *
- * 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 <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <asm/gt64240.h>
-#include <asm/io.h>
-
-unsigned long bus_clock;
-
-/*
- * These are interrupt handlers for the GT on-chip interrupts. They
- * all come in to the MIPS on a single interrupt line, and have to
- * be handled and ack'ed differently than other MIPS interrupts.
- */
-
-#if 0
-
-struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
-void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
-
-/*
- * Hooks IRQ handler to the system. When the system is interrupted
- * the interrupt service routine is called.
- *
- * Inputs :
- * int_cause - The interrupt cause number. In EVB64120 two parameters
- * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
- * bit_num - Indicates which bit number in the cause register
- * isr_ptr - Pointer to the interrupt service routine
- */
-void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
-{
- irq_handlers[int_cause][bit_num].routine = isr_ptr;
-}
-
-
-/*
- * Enables the IRQ on Galileo Chip
- *
- * Inputs :
- * int_cause - The interrupt cause number. In EVB64120 two parameters
- * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
- * bit_num - Indicates which bit number in the cause register
- *
- * Outputs :
- * 1 if successful, 0 if failure
- */
-int enable_galileo_irq(int int_cause, int bit_num)
-{
- if (int_cause == INT_CAUSE_MAIN)
- SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
- else if (int_cause == INT_CAUSE_HIGH)
- SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
- (1 << bit_num));
- else
- return 0;
-
- return 1;
-}
-
-/*
- * Disables the IRQ on Galileo Chip
- *
- * Inputs :
- * int_cause - The interrupt cause number. In EVB64120 two parameters
- * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
- * bit_num - Indicates which bit number in the cause register
- *
- * Outputs :
- * 1 if successful, 0 if failure
- */
-int disable_galileo_irq(int int_cause, int bit_num)
-{
- if (int_cause == INT_CAUSE_MAIN)
- RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
- (1 << bit_num));
- else if (int_cause == INT_CAUSE_HIGH)
- RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
- (1 << bit_num));
- else
- return 0;
- return 1;
-}
-#endif /* 0 */
-
-/*
- * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#.
- *
- * We route the timer interrupt to P0_INT# (IRQ 6), and that's all this
- * routine can handle, for now.
- *
- * In the future, we'll route more interrupts to this pin, and that's why
- * we keep this particular structure in the function.
- */
-
-static irqreturn_t gt64240_p0int_irq(int irq, void *dev)
-{
- uint32_t irq_src, irq_src_mask;
- int handled;
-
- /* get the low interrupt cause register */
- irq_src = MV_READ(LOW_INTERRUPT_CAUSE_REGISTER);
-
- /* get the mask register for this pin */
- irq_src_mask = MV_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW);
-
- /* mask off only the interrupts we're interested in */
- irq_src = irq_src & irq_src_mask;
-
- handled = IRQ_NONE;
-
- /* Check for timer interrupt */
- if (irq_src & 0x00000100) {
- handled = IRQ_HANDLED;
- irq_src &= ~0x00000100;
-
- /* Clear any pending cause bits */
- MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
-
- /* handle the timer call */
- do_timer(1);
-#ifndef CONFIG_SMP
- update_process_times(user_mode(get_irq_regs()));
-#endif
- }
-
- if (irq_src) {
- printk(KERN_INFO
- "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n",
- irq_src);
- }
-
- return handled;
-}
-
-/*
- * Initializes timer using galileo's built in timer.
- */
-
-/*
- * This will ignore the standard MIPS timer interrupt handler
- * that is passed in as *irq (=irq0 in ../kernel/time.c).
- * We will do our own timer interrupt handling.
- */
-void gt64240_time_init(void)
-{
- static struct irqaction timer;
-
- /* Stop the timer -- we'll use timer #0 */
- MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x0);
-
- /* Load timer value for 100 Hz */
- MV_WRITE(TIMER_COUNTER0, bus_clock / 100);
-
- /*
- * Create the IRQ structure entry for the timer. Since we're too early
- * in the boot process to use the "request_irq()" call, we'll hard-code
- * the values to the correct interrupt line.
- */
- timer.handler = &gt64240_p0int_irq;
- timer.flags = IRQF_SHARED | IRQF_DISABLED;
- timer.name = "timer";
- timer.dev_id = NULL;
- timer.next = NULL;
- timer.mask = CPU_MASK_NONE;
- irq_desc[6].action = &timer;
-
- enable_irq(6);
-
- /* Clear any pending cause bits */
- MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0);
-
- /* Enable the interrupt for timer 0 */
- MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_MASK, 0x1);
-
- /* Enable the timer interrupt for GT-64240 pin P0_INT# */
- MV_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0x100);
-
- /* Configure and start the timer */
- MV_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x3);
-}
-
-void gt64240_irq_init(void)
-{
-#if 0
- int i, j;
-
- /* Reset irq handlers pointers to NULL */
- for (i = 0; i < MAX_CAUSE_REGS; i++) {
- for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
- irq_handlers[i][j].next = NULL;
- irq_handlers[i][j].sync = 0;
- irq_handlers[i][j].routine = NULL;
- irq_handlers[i][j].data = NULL;
- }
- }
-#endif /* 0 */
-}
diff --git a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c
deleted file mode 100644
index 273541fe708..00000000000
--- a/arch/mips/momentum/ocelot_g/irq.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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 <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-asmlinkage void plat_irq_dispatch(void)
-{
- unsigned int pending = read_c0_cause() & read_c0_status();
-
- if (pending & STATUSF_IP2)
- do_IRQ(2);
- else if (pending & STATUSF_IP3)
- do_IRQ(3);
- else if (pending & STATUSF_IP4)
- do_IRQ(4);
- else if (pending & STATUSF_IP5)
- do_IRQ(5);
- else if (pending & STATUSF_IP6)
- do_IRQ(6);
- else if (pending & STATUSF_IP7)
- do_IRQ(7);
- else {
- /*
- * Now look at the extended interrupts
- */
- pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
-
- if (pending & STATUSF_IP8)
- do_IRQ(8);
- else if (pending & STATUSF_IP9)
- do_IRQ(9);
- else if (pending & STATUSF_IP10)
- do_IRQ(10);
- else if (pending & STATUSF_IP11)
- do_IRQ(11);
- else
- spurious_interrupt();
- }
-}
-
-extern void gt64240_irq_init(void);
-
-void __init arch_init_irq(void)
-{
- /*
- * Clear all of the interrupts while we change the able around a bit.
- * int-handler is not on bootstrap
- */
- clear_c0_status(ST0_IM);
- local_irq_disable();
-
- mips_cpu_irq_init();
- rm7k_cpu_irq_init();
-
- gt64240_irq_init();
-}
diff --git a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h
deleted file mode 100644
index 95e0534026d..00000000000
--- a/arch/mips/momentum/ocelot_g/ocelot_pld.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Ocelot Board Register Definitions
- *
- * (C) 2001 Red Hat, Inc.
- *
- * GPL'd
- */
-#ifndef __MOMENCO_OCELOT_PLD_H__
-#define __MOMENCO_OCELOT_PLD_H__
-
-#define OCELOT_CS0_ADDR (0xfc000000)
-
-#define OCELOT_REG_BOARDREV (0)
-#define OCELOT_REG_PLD1_ID (1)
-#define OCELOT_REG_PLD2_ID (2)
-#define OCELOT_REG_RESET_STATUS (3)
-#define OCELOT_REG_BOARD_STATUS (4)
-#define OCELOT_REG_CPCI_ID (5)
-#define OCELOT_REG_I2C_CTRL (8)
-#define OCELOT_REG_EEPROM_MODE (9)
-#define OCELOT_REG_INTMASK (10)
-#define OCELOT_REG_INTSTATUS (11)
-#define OCELOT_REG_INTSET (12)
-#define OCELOT_REG_INTCLR (13)
-
-#define __PLD_REG_TO_ADDR(reg) ((void *) OCELOT_CS0_ADDR + OCELOT_REG_##reg)
-#define OCELOT_PLD_WRITE(x, reg) writeb(x, __PLD_REG_TO_ADDR(reg))
-#define OCELOT_PLD_READ(reg) readb(__PLD_REG_TO_ADDR(reg))
-
-#endif /* __MOMENCO_OCELOT_PLD_H__ */
diff --git a/arch/mips/momentum/ocelot_g/prom.c b/arch/mips/momentum/ocelot_g/prom.c
deleted file mode 100644
index 836d0830720..00000000000
--- a/arch/mips/momentum/ocelot_g/prom.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2002 Momentum Computer Inc.
- * Author: Matthew Dharm <mdharm@momenco.com>
- *
- * Based on Ocelot Linux port, which is
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * 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 <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
-#include <asm/pmon.h>
-#include <asm/gt64240.h>
-
-#include "ocelot_pld.h"
-
-struct callvectors* debug_vectors;
-
-extern unsigned long marvell_base;
-extern unsigned long bus_clock;
-
-#ifdef CONFIG_GALILEO_GT64240_ETH
-extern unsigned char prom_mac_addr_base[6];
-#endif
-
-const char *get_system_type(void)
-{
- return "Momentum Ocelot";
-}
-
-void __init prom_init(void)
-{
- int argc = fw_arg0;
- char **arg = (char **) fw_arg1;
- char **env = (char **) fw_arg2;
- struct callvectors *cv = (struct callvectors *) fw_arg3;
- int i;
-
- /* save the PROM vectors for debugging use */
- debug_vectors = cv;
-
- /* arg[0] is "g", the rest is boot parameters */
- arcs_cmdline[0] = '\0';
- for (i = 1; i < argc; i++) {
- if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
- >= sizeof(arcs_cmdline))
- break;
- strcat(arcs_cmdline, arg[i]);
- strcat(arcs_cmdline, " ");
- }
-
- mips_machgroup = MACH_GROUP_MOMENCO;
- mips_machtype = MACH_MOMENCO_OCELOT_G;
-
-#ifdef CONFIG_GALILEO_GT64240_ETH
- /* get the base MAC address for on-board ethernet ports */
- memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
-#endif
-
- while (*env) {
- if (strncmp("gtbase", *env, strlen("gtbase")) == 0) {
- marvell_base = simple_strtol(*env + strlen("gtbase="),
- NULL, 16);
- }
- if (strncmp("busclock", *env, strlen("busclock")) == 0) {
- bus_clock = simple_strtol(*env + strlen("busclock="),
- NULL, 10);
- }
- env++;
- }
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
diff --git a/arch/mips/momentum/ocelot_g/reset.c b/arch/mips/momentum/ocelot_g/reset.c
deleted file mode 100644
index 3fd499adf4c..00000000000
--- a/arch/mips/momentum/ocelot_g/reset.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 1997, 2001 Ralf Baechle
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <asm/system.h>
-#include <linux/delay.h>
-
-void momenco_ocelot_restart(char *command)
-{
- void *nvram = ioremap_nocache(0x2c807000, 0x1000);
-
- if (!nvram) {
- printk(KERN_NOTICE "ioremap of reset register failed\n");
- return;
- }
- writeb(0x84, nvram + 0xff7); /* Ask the NVRAM/RTC/watchdog chip to
- assert reset in 1/16 second */
- mdelay(10+(1000/16));
- iounmap(nvram);
- printk(KERN_NOTICE "Watchdog reset failed\n");
-}
-
-void momenco_ocelot_halt(void)
-{
- printk(KERN_NOTICE "\n** You can safely turn off the power\n");
- while (1)
- __asm__(".set\tmips3\n\t"
- "wait\n\t"
- ".set\tmips0");
-}
-
-void momenco_ocelot_power_off(void)
-{
- momenco_ocelot_halt();
-}
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
deleted file mode 100644
index 9db638a7982..00000000000
--- a/arch/mips/momentum/ocelot_g/setup.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines
- *
- * Copyright (C) 1996, 1997, 2001 Ralf Baechle
- * Copyright (C) 2000 RidgeRun, Inc.
- * Copyright (C) 2001 Red Hat, Inc.
- * Copyright (C) 2002 Momentum Computer
- *
- * Author: Matthew Dharm, Momentum Computer
- * mdharm@momenco.com
- *
- * Author: RidgeRun, Inc.
- * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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 <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/timex.h>
-#include <linux/vmalloc.h>
-
-#include <asm/time.h>
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/gt64240.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/reboot.h>
-#include <linux/bootmem.h>
-
-#include "ocelot_pld.h"
-
-#ifdef CONFIG_GALILEO_GT64240_ETH
-extern unsigned char prom_mac_addr_base[6];
-#endif
-
-unsigned long marvell_base;
-
-/* These functions are used for rebooting or halting the machine*/
-extern void momenco_ocelot_restart(char *command);
-extern void momenco_ocelot_halt(void);
-extern void momenco_ocelot_power_off(void);
-
-extern void gt64240_time_init(void);
-extern void momenco_ocelot_irq_setup(void);
-
-static char reset_reason;
-
-static unsigned long ENTRYLO(unsigned long paddr)
-{
- return ((paddr & PAGE_MASK) |
- (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
- _CACHE_UNCACHED)) >> 6;
-}
-
-/* setup code for a handoff from a version 2 PMON 2000 PROM */
-void PMON_v2_setup(void)
-{
- /* A wired TLB entry for the GT64240 and the serial port. The
- GT64240 is going to be hit on every IRQ anyway - there's
- absolutely no point in letting it be a random TLB entry, as
- it'll just cause needless churning of the TLB. And we use
- the other half for the serial port, which is just a PITA
- otherwise :)
-
- Device Physical Virtual
- GT64240 Internal Regs 0xf4000000 0xe0000000
- UARTs (CS2) 0xfd000000 0xe0001000
- */
- add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000),
- 0xf4000000, PM_64K);
- add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000),
- 0xfd000000, PM_4K);
-
- /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
- in the CS[012] region. We can't use ioremap() yet. The NVRAM
- is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.
-
- Ocelot PLD (CS0) 0xfc000000 0xe0020000
- NVRAM (CS1) 0xfc800000 0xe0030000
- */
- add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000),
- 0xfc000000, PM_64K);
- add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000),
- 0xfc800000, PM_64K);
-
- marvell_base = 0xf4000000;
-}
-
-extern int rm7k_tcache_enabled;
-
-/*
- * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
- */
-#define Page_Invalidate_T 0x16
-static void __init setup_l3cache(unsigned long size)
-{
- int register i;
-
- printk("Enabling L3 cache...");
-
- /* Enable the L3 cache in the GT64120A's CPU Configuration register */
- MV_WRITE(0, MV_READ(0) | (1<<14));
-
- /* Enable the L3 cache in the CPU */
- set_c0_config(1<<12 /* CONF_TE */);
-
- /* Clear the cache */
- write_c0_taglo(0);
- write_c0_taghi(0);
-
- for (i=0; i < size; i+= 4096) {
- __asm__ __volatile__ (
- ".set noreorder\n\t"
- ".set mips3\n\t"
- "cache %1, (%0)\n\t"
- ".set mips0\n\t"
- ".set reorder"
- :
- : "r" (KSEG0ADDR(i)),
- "i" (Page_Invalidate_T));
- }
-
- /* Let the RM7000 MM code know that the tertiary cache is enabled */
- rm7k_tcache_enabled = 1;
-
- printk("Done\n");
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-}
-
-void __init plat_mem_setup(void)
-{
- void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
- unsigned int tmpword;
-
- board_time_init = gt64240_time_init;
-
- _machine_restart = momenco_ocelot_restart;
- _machine_halt = momenco_ocelot_halt;
- pm_power_off = momenco_ocelot_power_off;
-
- /*
- * initrd_start = (unsigned long)ocelot_initrd_start;
- * initrd_end = (unsigned long)ocelot_initrd_start + (ulong)ocelot_initrd_size;
- * initrd_below_start_ok = 1;
- */
-
- /* do handoff reconfiguration */
- PMON_v2_setup();
-
-#ifdef CONFIG_GALILEO_GT64240_ETH
- /* get the mac addr */
- memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
-#endif
-
- /* Turn off the Bit-Error LED */
- OCELOT_PLD_WRITE(0x80, INTCLR);
-
- tmpword = OCELOT_PLD_READ(BOARDREV);
- if (tmpword < 26)
- printk("Momenco Ocelot-G: Board Assembly Rev. %c\n", 'A'+tmpword);
- else
- printk("Momenco Ocelot-G: Board Assembly Revision #0x%x\n", tmpword);
-
- tmpword = OCELOT_PLD_READ(PLD1_ID);
- printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
- tmpword = OCELOT_PLD_READ(PLD2_ID);
- printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
- tmpword = OCELOT_PLD_READ(RESET_STATUS);
- printk("Reset reason: 0x%x\n", tmpword);
- reset_reason = tmpword;
- OCELOT_PLD_WRITE(0xff, RESET_STATUS);
-
- tmpword = OCELOT_PLD_READ(BOARD_STATUS);
- printk("Board Status register: 0x%02x\n", tmpword);
- printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
- printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
- printk(" - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
- printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
- printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));
-
- if (tmpword&12)
- l3func((1<<(((tmpword&12) >> 2)+20)));
-
- switch(tmpword &3) {
- case 3:
- /* 512MiB -- two banks of 256MiB */
- add_memory_region( 0x0<<20, 0x100<<20, BOOT_MEM_RAM);
-/*
- add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
-*/
- break;
- case 2:
- /* 256MiB -- two banks of 128MiB */
- add_memory_region( 0x0<<20, 0x80<<20, BOOT_MEM_RAM);
- add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
- break;
- case 1:
- /* 128MiB -- 64MiB per bank */
- add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
- add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
- break;
- case 0:
- /* 64MiB */
- add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
- break;
- }
-
- /* FIXME: Fix up the DiskOnChip mapping */
- MV_WRITE(0x468, 0xfef73);
-}
-
-/* This needs to be one of the first initcalls, because no I/O port access
- can work before this */
-
-static int io_base_ioremap(void)
-{
- /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
- unsigned long io_remap_range;
-
- io_remap_range = (unsigned long) ioremap(0xc0000000, 0x30000000);
- if (!io_remap_range)
- panic("Could not ioremap I/O port range");
-
- set_io_port_base(io_remap_range - 0xc0000000);
-
- return 0;
-}
-
-module_init(io_base_ioremap);
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index df487c063b1..aba3dbf47ed 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -30,11 +30,9 @@ obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o
-obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o
obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o
obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o
obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o
-obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o pci-ocelot-g.o
obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
pci-yosemite.o
obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index 7d5f6bbf7a9..d57ffd7242c 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -17,9 +17,7 @@
#include <asm/io.h>
#include <asm/gt64120.h>
-#include <asm/mach-cobalt/cobalt.h>
-
-extern int cobalt_board_id;
+#include <cobalt.h>
static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
{
@@ -115,6 +113,27 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
qube_raq_galileo_fixup);
+int cobalt_board_id;
+
+static void qube_raq_via_board_id_fixup(struct pci_dev *dev)
+{
+ u8 id;
+ int retval;
+
+ retval = pci_read_config_byte(dev, VIA_COBALT_BRD_ID_REG, &id);
+ if (retval) {
+ panic("Cannot read board ID");
+ return;
+ }
+
+ cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(id);
+
+ printk(KERN_INFO "Cobalt board ID: %d\n", cobalt_board_id);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0,
+ qube_raq_via_board_id_fixup);
+
static char irq_tab_qube1[] __initdata = {
[COBALT_PCICONF_CPU] = 0,
[COBALT_PCICONF_ETH0] = COBALT_QUBE1_ETH0_IRQ,
diff --git a/arch/mips/pci/fixup-jaguar.c b/arch/mips/pci/fixup-jaguar.c
deleted file mode 100644
index 6c5e1d47179..00000000000
--- a/arch/mips/pci/fixup-jaguar.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- *
- * Marvell MV64340 interrupt fixup code.
- *
- * Marvell wants an NDA for their docs so this was written without
- * documentation. You've been warned.
- *
- * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-
-#include <asm/mipsregs.h>
-
-/*
- * WARNING: Example of how _NOT_ to do it.
- */
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- int bus = dev->bus->number;
-
- if (bus == 0 && slot == 1)
- return 3; /* PCI-X A */
- if (bus == 0 && slot == 2)
- return 4; /* PCI-X B */
- if (bus == 1 && slot == 1)
- return 5; /* PCI A */
- if (bus == 1 && slot == 2)
- return 6; /* PCI B */
-
-return 0;
- panic("Whooops in pcibios_map_irq");
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
- return 0;
-}
diff --git a/arch/mips/pci/fixup-ocelot-g.c b/arch/mips/pci/fixup-ocelot-g.c
deleted file mode 100644
index d7a652e326c..00000000000
--- a/arch/mips/pci/fixup-ocelot-g.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- int bus = dev->bus->number;
-
- if (bus == 0 && slot == 1) /* Intel 82543 Gigabit MAC */
- return 2; /* irq_nr is 2 for INT0 */
-
- if (bus == 0 && slot == 2) /* Intel 82543 Gigabit MAC */
- return 3; /* irq_nr is 3 for INT1 */
-
- if (bus == 1 && slot == 3) /* Intel 21555 bridge */
- return 5; /* irq_nr is 8 for INT6 */
-
- if (bus == 1 && slot == 4) /* PMC Slot */
- return 9; /* irq_nr is 9 for INT7 */
-
- return -1;
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
- return 0;
-}
diff --git a/arch/mips/pci/pci-ocelot-g.c b/arch/mips/pci/pci-ocelot-g.c
deleted file mode 100644
index 1e3430154fa..00000000000
--- a/arch/mips/pci/pci-ocelot-g.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
- *
- * This doesn't really fly - but I don't have a GT64240 system for testing.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/gt64240.h>
-
-/*
- * We assume these address ranges have been programmed into the GT-64240 by
- * the firmware. PMON in case of the Ocelot G does that. Note the size of
- * the I/O range is completly stupid; I/O mappings are limited to at most
- * 256 bytes by the PCI spec and deprecated; and just to make things worse
- * apparently many devices don't decode more than 64k of I/O space.
- */
-
-#define gt_io_size 0x20000000UL
-#define gt_io_base 0xe0000000UL
-
-static struct resource gt_pci_mem0_resource = {
- .name = "MV64240 PCI0 MEM",
- .start = 0xc0000000UL,
- .end = 0xcfffffffUL,
- .flags = IORESOURCE_MEM
-};
-
-static struct resource gt_pci_io_mem0_resource = {
- .name = "MV64240 PCI0 IO MEM",
- .start = 0xe0000000UL,
- .end = 0xefffffffUL,
- .flags = IORESOURCE_IO
-};
-
-static struct mv_pci_controller gt_bus0_controller = {
- .pcic = {
- .pci_ops = &mv_pci_ops,
- .mem_resource = &gt_pci_mem0_resource,
- .mem_offset = 0xc0000000UL,
- .io_resource = &gt_pci_io_mem0_resource,
- .io_offset = 0x00000000UL
- },
- .config_addr = PCI_0CONFIGURATION_ADDRESS,
- .config_vreg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
-};
-
-static struct resource gt_pci_mem1_resource = {
- .name = "MV64240 PCI1 MEM",
- .start = 0xd0000000UL,
- .end = 0xdfffffffUL,
- .flags = IORESOURCE_MEM
-};
-
-static struct resource gt_pci_io_mem1_resource = {
- .name = "MV64240 PCI1 IO MEM",
- .start = 0xf0000000UL,
- .end = 0xffffffffUL,
- .flags = IORESOURCE_IO
-};
-
-static struct mv_pci_controller gt_bus1_controller = {
- .pcic = {
- .pci_ops = &mv_pci_ops,
- .mem_resource = &gt_pci_mem1_resource,
- .mem_offset = 0xd0000000UL,
- .io_resource = &gt_pci_io_mem1_resource,
- .io_offset = 0x10000000UL
- },
- .config_addr = PCI_1CONFIGURATION_ADDRESS,
- .config_vreg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,
-};
-
-static __init int __init ocelot_g_pci_init(void)
-{
- unsigned long io_v_base;
-
- if (gt_io_size) {
- io_v_base = (unsigned long) ioremap(gt_io_base, gt_io_size);
- if (!io_v_base)
- panic("Could not ioremap I/O port range");
-
- set_io_port_base(io_v_base);
- }
-
- register_pci_controller(&gt_bus0_controller.pcic);
- register_pci_controller(&gt_bus1_controller.pcic);
-
- return 0;
-}
-
-arch_initcall(ocelot_g_pci_init);
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index b6d649241dc..1fb3e353e21 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -4,6 +4,6 @@
#
obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \
- ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o
+ ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o
obj-$(CONFIG_EISA) += ip22-eisa.o
diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c
new file mode 100644
index 00000000000..78b608d2d4e
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-platform.c
@@ -0,0 +1,177 @@
+#include <linux/init.h>
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/paccess.h>
+#include <asm/sgi/ip22.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/seeq.h>
+#include <asm/sgi/wd.h>
+
+static struct resource sgiwd93_0_resources[] = {
+ {
+ .name = "eth0 irq",
+ .start = SGI_WD93_0_IRQ,
+ .end = SGI_WD93_0_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiwd93_platform_data sgiwd93_0_pd = {
+ .unit = 0,
+ .irq = SGI_WD93_0_IRQ,
+};
+
+static struct platform_device sgiwd93_0_device = {
+ .name = "sgiwd93",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sgiwd93_0_resources),
+ .resource = sgiwd93_0_resources,
+ .dev = {
+ .platform_data = &sgiwd93_0_pd,
+ },
+};
+
+static struct resource sgiwd93_1_resources[] = {
+ {
+ .name = "eth0 irq",
+ .start = SGI_WD93_1_IRQ,
+ .end = SGI_WD93_1_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiwd93_platform_data sgiwd93_1_pd = {
+ .unit = 1,
+ .irq = SGI_WD93_1_IRQ,
+};
+
+static struct platform_device sgiwd93_1_device = {
+ .name = "sgiwd93",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sgiwd93_1_resources),
+ .resource = sgiwd93_1_resources,
+ .dev = {
+ .platform_data = &sgiwd93_1_pd,
+ },
+};
+
+/*
+ * Create a platform device for the GPI port that receives the
+ * image data from the embedded camera.
+ */
+static int __init sgiwd93_devinit(void)
+{
+ int res;
+
+ sgiwd93_0_pd.hregs = &hpc3c0->scsi_chan0;
+ sgiwd93_0_pd.wdregs = (unsigned char *) hpc3c0->scsi0_ext;
+
+ res = platform_device_register(&sgiwd93_0_device);
+ if (res)
+ return res;
+
+ if (!ip22_is_fullhouse())
+ return 0;
+
+ sgiwd93_1_pd.hregs = &hpc3c0->scsi_chan1;
+ sgiwd93_1_pd.wdregs = (unsigned char *) hpc3c0->scsi1_ext;
+
+ return platform_device_register(&sgiwd93_1_device);
+}
+
+device_initcall(sgiwd93_devinit);
+
+static struct resource sgiseeq_0_resources[] = {
+ {
+ .name = "eth0 irq",
+ .start = SGI_ENET_IRQ,
+ .end = SGI_ENET_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiseeq_platform_data eth0_pd;
+
+static struct platform_device eth0_device = {
+ .name = "sgiseeq",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sgiseeq_0_resources),
+ .resource = sgiseeq_0_resources,
+ .dev = {
+ .platform_data = &eth0_pd,
+ },
+};
+
+static struct resource sgiseeq_1_resources[] = {
+ {
+ .name = "eth1 irq",
+ .start = SGI_GIO_0_IRQ,
+ .end = SGI_GIO_0_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiseeq_platform_data eth1_pd;
+
+static struct platform_device eth1_device = {
+ .name = "sgiseeq",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sgiseeq_1_resources),
+ .resource = sgiseeq_1_resources,
+ .dev = {
+ .platform_data = &eth1_pd,
+ },
+};
+
+/*
+ * Create a platform device for the GPI port that receives the
+ * image data from the embedded camera.
+ */
+static int __init sgiseeq_devinit(void)
+{
+ unsigned int tmp;
+ int res, i;
+
+ eth0_pd.hpc = hpc3c0;
+ eth0_pd.irq = SGI_ENET_IRQ;
+#define EADDR_NVOFS 250
+ for (i = 0; i < 3; i++) {
+ unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i);
+
+ eth0_pd.mac[2 * i] = tmp >> 8;
+ eth0_pd.mac[2 * i + 1] = tmp & 0xff;
+ }
+
+ res = platform_device_register(&eth0_device);
+ if (res)
+ return res;
+
+ /* Second HPC is missing? */
+ if (ip22_is_fullhouse() ||
+ !get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]))
+ return 0;
+
+ sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 |
+ SGIMC_GIOPAR_HPC264;
+ hpc3c1->pbus_piocfg[0][0] = 0x3ffff;
+ /* interrupt/config register on Challenge S Mezz board */
+ hpc3c1->pbus_extregs[0][0] = 0x30;
+
+ eth1_pd.hpc = hpc3c1;
+ eth1_pd.irq = SGI_GIO_0_IRQ;
+#define EADDR_NVOFS 250
+ for (i = 0; i < 3; i++) {
+ unsigned short tmp = ip22_eeprom_read(&hpc3c1->eeprom,
+ EADDR_NVOFS / 2 + i);
+
+ eth1_pd.mac[2 * i] = tmp >> 8;
+ eth1_pd.mac[2 * i + 1] = tmp & 0xff;
+ }
+
+ return platform_device_register(&eth1_device);
+}
+
+device_initcall(sgiseeq_devinit);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ccc5410af99..56d3c0dcd2b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -389,6 +389,9 @@ config NOT_COHERENT_CACHE
bool
depends on 4xx || 8xx || E200
default y
+
+config CONFIG_CHECK_CACHE_COHERENCY
+ bool
endmenu
source "init/Kconfig"
@@ -451,7 +454,7 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on PPC_MULTIPLATFORM && EXPERIMENTAL
+ depends on (PPC_PRPMC2800 || PPC_MULTIPLATFORM) && EXPERIMENTAL
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 81a531d84ff..d6014a67694 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE)
CPPFLAGS_vmlinux.lds := -Upowerpc
-BOOT_TARGETS = zImage zImage.initrd uImage
+BOOT_TARGETS = zImage zImage.initrd zImage.dts zImage.dts_initrd uImage
PHONY += $(BOOT_TARGETS)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 5c384aad118..d4f9fef7f9e 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -43,9 +43,9 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c \
- 44x.c ebony.c
+ 44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c
src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
- cuboot-ebony.c treeboot-ebony.c
+ cuboot-ebony.c treeboot-ebony.c prpmc2800.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -132,6 +132,7 @@ image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
image-$(CONFIG_PPC_PMAC) += zImage.pmac
image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf
+image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
image-$(CONFIG_DEFAULT_UIMAGE) += uImage
ifneq ($(CONFIG_DEVICE_TREE),"")
@@ -154,9 +155,27 @@ targets += $(image-y) $(initrd-y)
$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
+dts- := $(patsubst zImage%, zImage.dts%, $(image-n) $(image-))
+dts-y := $(patsubst zImage%, zImage.dts%, $(image-y))
+dts-y := $(filter-out $(image-y), $(dts-y))
+targets += $(image-y) $(dts-y)
+
+dts_initrd- := $(patsubst zImage%, zImage.dts_initrd%, $(image-n) $(image-))
+dts_initrd-y := $(patsubst zImage%, zImage.dts_initrd%, $(image-y))
+dts_initrd-y := $(filter-out $(image-y), $(dts_initrd-y))
+targets += $(image-y) $(dts_initrd-y)
+
+$(addprefix $(obj)/, $(dts_initrd-y)): $(obj)/ramdisk.image.gz
+
# Don't put the ramdisk on the pattern rule; when its missing make will try
# the pattern rule with less dependencies that also matches (even with the
# hard dependency listed).
+$(obj)/zImage.dts_initrd.%: vmlinux $(wrapperbits) $(dts) $(obj)/ramdisk.image.gz
+ $(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz)
+
+$(obj)/zImage.dts.%: vmlinux $(wrapperbits) $(dts)
+ $(call if_changed,wrap,$*,$(dts))
+
$(obj)/zImage.initrd.%: vmlinux $(wrapperbits)
$(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz)
@@ -195,13 +214,18 @@ $(obj)/zImage: $(addprefix $(obj)/, $(image-y))
@rm -f $@; ln $< $@
$(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y))
@rm -f $@; ln $< $@
+$(obj)/zImage.dts: $(addprefix $(obj)/, $(dts-y))
+ @rm -f $@; ln $< $@
+$(obj)/zImage.dts_initrd: $(addprefix $(obj)/, $(dts_initrd-y))
+ @rm -f $@; ln $< $@
+
install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y))
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
# anything not in $(targets)
clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \
- treeImage.*
+ treeImage.* zImage.dts zImage.dts_initrd
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin
diff --git a/arch/powerpc/boot/cuboot-83xx.c b/arch/powerpc/boot/cuboot-83xx.c
index 6cbc20afb4d..9af554eea54 100644
--- a/arch/powerpc/boot/cuboot-83xx.c
+++ b/arch/powerpc/boot/cuboot-83xx.c
@@ -57,7 +57,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
memcpy(&bd, (bd_t *)r3, sizeof(bd));
loader_info.initrd_addr = r4;
- loader_info.initrd_size = r4 ? r5 : 0;
+ loader_info.initrd_size = r4 ? r5 - r4 : 0;
loader_info.cmdline = (char *)r6;
loader_info.cmdline_len = r7 - r6;
diff --git a/arch/powerpc/boot/cuboot-85xx.c b/arch/powerpc/boot/cuboot-85xx.c
index f88ba00ac12..e2560317f27 100644
--- a/arch/powerpc/boot/cuboot-85xx.c
+++ b/arch/powerpc/boot/cuboot-85xx.c
@@ -58,7 +58,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
memcpy(&bd, (bd_t *)r3, sizeof(bd));
loader_info.initrd_addr = r4;
- loader_info.initrd_size = r4 ? r5 : 0;
+ loader_info.initrd_size = r4 ? r5 - r4 : 0;
loader_info.cmdline = (char *)r6;
loader_info.cmdline_len = r7 - r6;
diff --git a/arch/powerpc/boot/dts/prpmc2800.dts b/arch/powerpc/boot/dts/prpmc2800.dts
new file mode 100644
index 00000000000..568965a022b
--- /dev/null
+++ b/arch/powerpc/boot/dts/prpmc2800.dts
@@ -0,0 +1,315 @@
+/* Device Tree Source for Motorola PrPMC2800
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Property values that are labeled as "Default" will be updated by bootwrapper
+ * if it can determine the exact PrPMC type.
+ *
+ * To build:
+ * dtc -I dts -O asm -o prpmc2800.S -b 0 prpmc2800.dts
+ * dtc -I dts -O dtb -o prpmc2800.dtb -b 0 prpmc2800.dts
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "PrPMC280/PrPMC2800"; /* Default */
+ compatible = "motorola,PrPMC2800";
+ coherency-off;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,7447 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <2bb0b140>; /* Default (733 MHz) */
+ bus-frequency = <7f28155>; /* 133.333333 MHz */
+ timebase-frequency = <1fca055>; /* 33.333333 MHz */
+ i-cache-line-size = <20>;
+ d-cache-line-size = <20>;
+ i-cache-size = <8000>;
+ d-cache-size = <8000>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <00000000 20000000>; /* Default (512MB) */
+ };
+
+ mv64x60@f1000000 { /* Marvell Discovery */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+ model = "mv64360"; /* Default */
+ compatible = "marvell,mv64x60";
+ clock-frequency = <7f28155>; /* 133.333333 MHz */
+ reg = <f1000000 00010000>;
+ virtual-reg = <f1000000>;
+ ranges = <88000000 88000000 01000000 /* PCI 0 I/O Space */
+ 80000000 80000000 08000000 /* PCI 0 MEM Space */
+ a0000000 a0000000 04000000 /* User FLASH */
+ 00000000 f1000000 00010000 /* Bridge's regs */
+ f2000000 f2000000 00040000>; /* Integrated SRAM */
+
+ flash@a0000000 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ reg = <a0000000 4000000>; /* Default (64MB) */
+ probe-type = "CFI";
+ bank-width = <4>;
+ partitions = <00000000 00100000 /* RO */
+ 00100000 00040001 /* RW */
+ 00140000 00400000 /* RO */
+ 00540000 039c0000 /* RO */
+ 03f00000 00100000>; /* RO */
+ partition-names = "FW Image A", "FW Config Data", "Kernel Image", "Filesystem", "FW Image B";
+ };
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "marvell,mv64x60-mdio";
+ ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "broadcom,bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <1>;
+ };
+ ethernet-phy@3 {
+ device_type = "ethernet-phy";
+ compatible = "broadcom,bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <3>;
+ };
+ };
+
+ ethernet@2000 {
+ reg = <2000 2000>;
+ eth0 {
+ device_type = "network";
+ compatible = "marvell,mv64x60-eth";
+ block-index = <0>;
+ interrupts = <20>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ eth1 {
+ device_type = "network";
+ compatible = "marvell,mv64x60-eth";
+ block-index = <1>;
+ interrupts = <21>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@3>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ sdma@4000 {
+ device_type = "dma";
+ compatible = "marvell,mv64x60-sdma";
+ reg = <4000 c18>;
+ virtual-reg = <f1004000>;
+ interrupt-base = <0>;
+ interrupts = <24>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sdma@6000 {
+ device_type = "dma";
+ compatible = "marvell,mv64x60-sdma";
+ reg = <6000 c18>;
+ virtual-reg = <f1006000>;
+ interrupt-base = <0>;
+ interrupts = <26>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ brg@b200 {
+ compatible = "marvell,mv64x60-brg";
+ reg = <b200 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ brg@b208 {
+ compatible = "marvell,mv64x60-brg";
+ reg = <b208 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ cunit@f200 {
+ reg = <f200 200>;
+ };
+
+ mpscrouting@b400 {
+ reg = <b400 c>;
+ };
+
+ mpscintr@b800 {
+ reg = <b800 100>;
+ virtual-reg = <f100b800>;
+ };
+
+ mpsc@8000 {
+ device_type = "serial";
+ compatible = "marvell,mpsc";
+ reg = <8000 38>;
+ virtual-reg = <f1008000>;
+ sdma = <&/mv64x60/sdma@4000>;
+ brg = <&/mv64x60/brg@b200>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <0>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <28>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ mpsc@9000 {
+ device_type = "serial";
+ compatible = "marvell,mpsc";
+ reg = <9000 38>;
+ virtual-reg = <f1009000>;
+ sdma = <&/mv64x60/sdma@6000>;
+ brg = <&/mv64x60/brg@b208>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <1>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <2a>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ i2c@c000 {
+ device_type = "i2c";
+ compatible = "marvell,mv64x60-i2c";
+ reg = <c000 20>;
+ virtual-reg = <f100c000>;
+ freq_m = <8>;
+ freq_n = <3>;
+ timeout = <3e8>; /* 1000 = 1 second */
+ retries = <1>;
+ interrupts = <25>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pic {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ compatible = "marvell,mv64x60-pic";
+ reg = <0000 88>;
+ interrupt-controller;
+ };
+
+ mpp@f000 {
+ compatible = "marvell,mv64x60-mpp";
+ reg = <f000 10>;
+ };
+
+ gpp@f100 {
+ compatible = "marvell,mv64x60-gpp";
+ reg = <f100 20>;
+ };
+
+ pci@80000000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "marvell,mv64x60-pci";
+ reg = <0cf8 8>;
+ ranges = <01000000 0 0 88000000 0 01000000
+ 02000000 0 80000000 80000000 0 08000000>;
+ bus-range = <0 ff>;
+ clock-frequency = <3EF1480>;
+ interrupt-pci-iack = <0c34>;
+ interrupt-parent = <&/mv64x60/pic>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0a */
+ 5000 0 0 1 &/mv64x60/pic 50
+ 5000 0 0 2 &/mv64x60/pic 51
+ 5000 0 0 3 &/mv64x60/pic 5b
+ 5000 0 0 4 &/mv64x60/pic 5d
+
+ /* IDSEL 0x0b */
+ 5800 0 0 1 &/mv64x60/pic 5b
+ 5800 0 0 2 &/mv64x60/pic 5d
+ 5800 0 0 3 &/mv64x60/pic 50
+ 5800 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0c */
+ 6000 0 0 1 &/mv64x60/pic 5b
+ 6000 0 0 2 &/mv64x60/pic 5d
+ 6000 0 0 3 &/mv64x60/pic 50
+ 6000 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0d */
+ 6800 0 0 1 &/mv64x60/pic 5d
+ 6800 0 0 2 &/mv64x60/pic 50
+ 6800 0 0 3 &/mv64x60/pic 51
+ 6800 0 0 4 &/mv64x60/pic 5b
+ >;
+ };
+
+ cpu-error@0070 {
+ compatible = "marvell,mv64x60-cpu-error";
+ reg = <0070 10 0128 28>;
+ interrupts = <03>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sram-ctrl@0380 {
+ compatible = "marvell,mv64x60-sram-ctrl";
+ reg = <0380 80>;
+ interrupts = <0d>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pci-error@1d40 {
+ compatible = "marvell,mv64x60-pci-error";
+ reg = <1d40 40 0c28 4>;
+ interrupts = <0c>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ mem-ctrl@1400 {
+ compatible = "marvell,mv64x60-mem-ctrl";
+ reg = <1400 60>;
+ interrupts = <11>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+ };
+
+ chosen {
+ bootargs = "ip=on console=ttyMM0";
+ linux,stdout-path = "/mv64x60@f1000000/mpsc@8000";
+ };
+};
diff --git a/arch/powerpc/boot/mpsc.c b/arch/powerpc/boot/mpsc.c
new file mode 100644
index 00000000000..f1c0e965e5c
--- /dev/null
+++ b/arch/powerpc/boot/mpsc.c
@@ -0,0 +1,170 @@
+/*
+ * MPSC/UART driver for the Marvell mv64360, mv64460, ...
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+
+extern void udelay(long delay);
+
+#define MPSC_CHR_1 0x000c
+
+#define MPSC_CHR_2 0x0010
+#define MPSC_CHR_2_TA (1<<7)
+#define MPSC_CHR_2_TCS (1<<9)
+#define MPSC_CHR_2_RA (1<<23)
+#define MPSC_CHR_2_CRD (1<<25)
+#define MPSC_CHR_2_EH (1<<31)
+
+#define MPSC_CHR_4 0x0018
+#define MPSC_CHR_4_Z (1<<29)
+
+#define MPSC_CHR_5 0x001c
+#define MPSC_CHR_5_CTL1_INTR (1<<12)
+#define MPSC_CHR_5_CTL1_VALID (1<<15)
+
+#define MPSC_CHR_10 0x0030
+
+#define MPSC_INTR_CAUSE 0x0000
+#define MPSC_INTR_CAUSE_RCC (1<<6)
+#define MPSC_INTR_MASK 0x0080
+
+#define SDMA_SDCM 0x0008
+#define SDMA_SDCM_AR (1<<15)
+#define SDMA_SDCM_AT (1<<31)
+
+static volatile char *mpsc_base;
+static volatile char *mpscintr_base;
+static u32 chr1, chr2;
+
+static int mpsc_open(void)
+{
+ chr1 = in_le32((u32 *)(mpsc_base + MPSC_CHR_1)) & 0x00ff0000;
+ chr2 = in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & ~(MPSC_CHR_2_TA
+ | MPSC_CHR_2_TCS | MPSC_CHR_2_RA | MPSC_CHR_2_CRD
+ | MPSC_CHR_2_EH);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_4), MPSC_CHR_4_Z);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_5),
+ MPSC_CHR_5_CTL1_INTR | MPSC_CHR_5_CTL1_VALID);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_EH);
+ return 0;
+}
+
+static void mpsc_putc(unsigned char c)
+{
+ while (in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & MPSC_CHR_2_TCS);
+
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_1), chr1 | c);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_TCS);
+}
+
+static unsigned char mpsc_getc(void)
+{
+ u32 cause = 0;
+ unsigned char c;
+
+ while (!(cause & MPSC_INTR_CAUSE_RCC))
+ cause = in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE));
+
+ c = in_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2));
+ out_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2), c);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE),
+ cause & ~MPSC_INTR_CAUSE_RCC);
+
+ return c;
+}
+
+static u8 mpsc_tstc(void)
+{
+ return (u8)((in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE))
+ & MPSC_INTR_CAUSE_RCC) != 0);
+}
+
+static void mpsc_stop_dma(volatile char *sdma_base)
+{
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_2),MPSC_CHR_2_TA | MPSC_CHR_2_RA);
+ out_le32((u32 *)(sdma_base + SDMA_SDCM), SDMA_SDCM_AR | SDMA_SDCM_AT);
+
+ while ((in_le32((u32 *)(sdma_base + SDMA_SDCM))
+ & (SDMA_SDCM_AR | SDMA_SDCM_AT)) != 0)
+ udelay(100);
+}
+
+static volatile char *mpsc_get_virtreg_of_phandle(void *devp, char *prop)
+{
+ void *v;
+ int n;
+
+ n = getprop(devp, prop, &v, sizeof(v));
+ if (n != sizeof(v))
+ goto err_out;
+
+ devp = find_node_by_linuxphandle((u32)v);
+ if (devp == NULL)
+ goto err_out;
+
+ n = getprop(devp, "virtual-reg", &v, sizeof(v));
+ if (n == sizeof(v))
+ return v;
+
+err_out:
+ return NULL;
+}
+
+int mpsc_console_init(void *devp, struct serial_console_data *scdp)
+{
+ void *v;
+ int n, reg_set;
+ volatile char *sdma_base;
+
+ n = getprop(devp, "virtual-reg", &v, sizeof(v));
+ if (n != sizeof(v))
+ goto err_out;
+ mpsc_base = v;
+
+ sdma_base = mpsc_get_virtreg_of_phandle(devp, "sdma");
+ if (sdma_base == NULL)
+ goto err_out;
+
+ mpscintr_base = mpsc_get_virtreg_of_phandle(devp, "mpscintr");
+ if (mpscintr_base == NULL)
+ goto err_out;
+
+ n = getprop(devp, "block-index", &v, sizeof(v));
+ if (n != sizeof(v))
+ goto err_out;
+ reg_set = (int)v;
+
+ mpscintr_base += (reg_set == 0) ? 0x4 : 0xc;
+
+ /* Make sure the mpsc ctlrs are shutdown */
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
+
+ mpsc_stop_dma(sdma_base);
+
+ scdp->open = mpsc_open;
+ scdp->putc = mpsc_putc;
+ scdp->getc = mpsc_getc;
+ scdp->tstc = mpsc_tstc;
+ scdp->close = NULL;
+
+ return 0;
+
+err_out:
+ return -1;
+}
diff --git a/arch/powerpc/boot/mv64x60.c b/arch/powerpc/boot/mv64x60.c
new file mode 100644
index 00000000000..b43259455d4
--- /dev/null
+++ b/arch/powerpc/boot/mv64x60.c
@@ -0,0 +1,581 @@
+/*
+ * Marvell hostbridge routines
+ *
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 2004, 2005, 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+#include "mv64x60.h"
+
+#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+
+#define MV64x60_CPU2MEM_WINDOWS 4
+#define MV64x60_CPU2MEM_0_BASE 0x0008
+#define MV64x60_CPU2MEM_0_SIZE 0x0010
+#define MV64x60_CPU2MEM_1_BASE 0x0208
+#define MV64x60_CPU2MEM_1_SIZE 0x0210
+#define MV64x60_CPU2MEM_2_BASE 0x0018
+#define MV64x60_CPU2MEM_2_SIZE 0x0020
+#define MV64x60_CPU2MEM_3_BASE 0x0218
+#define MV64x60_CPU2MEM_3_SIZE 0x0220
+
+#define MV64x60_ENET2MEM_BAR_ENABLE 0x2290
+#define MV64x60_ENET2MEM_0_BASE 0x2200
+#define MV64x60_ENET2MEM_0_SIZE 0x2204
+#define MV64x60_ENET2MEM_1_BASE 0x2208
+#define MV64x60_ENET2MEM_1_SIZE 0x220c
+#define MV64x60_ENET2MEM_2_BASE 0x2210
+#define MV64x60_ENET2MEM_2_SIZE 0x2214
+#define MV64x60_ENET2MEM_3_BASE 0x2218
+#define MV64x60_ENET2MEM_3_SIZE 0x221c
+#define MV64x60_ENET2MEM_4_BASE 0x2220
+#define MV64x60_ENET2MEM_4_SIZE 0x2224
+#define MV64x60_ENET2MEM_5_BASE 0x2228
+#define MV64x60_ENET2MEM_5_SIZE 0x222c
+#define MV64x60_ENET2MEM_ACC_PROT_0 0x2294
+#define MV64x60_ENET2MEM_ACC_PROT_1 0x2298
+#define MV64x60_ENET2MEM_ACC_PROT_2 0x229c
+
+#define MV64x60_MPSC2MEM_BAR_ENABLE 0xf250
+#define MV64x60_MPSC2MEM_0_BASE 0xf200
+#define MV64x60_MPSC2MEM_0_SIZE 0xf204
+#define MV64x60_MPSC2MEM_1_BASE 0xf208
+#define MV64x60_MPSC2MEM_1_SIZE 0xf20c
+#define MV64x60_MPSC2MEM_2_BASE 0xf210
+#define MV64x60_MPSC2MEM_2_SIZE 0xf214
+#define MV64x60_MPSC2MEM_3_BASE 0xf218
+#define MV64x60_MPSC2MEM_3_SIZE 0xf21c
+#define MV64x60_MPSC_0_REMAP 0xf240
+#define MV64x60_MPSC_1_REMAP 0xf244
+#define MV64x60_MPSC2MEM_ACC_PROT_0 0xf254
+#define MV64x60_MPSC2MEM_ACC_PROT_1 0xf258
+#define MV64x60_MPSC2REGS_BASE 0xf25c
+
+#define MV64x60_IDMA2MEM_BAR_ENABLE 0x0a80
+#define MV64x60_IDMA2MEM_0_BASE 0x0a00
+#define MV64x60_IDMA2MEM_0_SIZE 0x0a04
+#define MV64x60_IDMA2MEM_1_BASE 0x0a08
+#define MV64x60_IDMA2MEM_1_SIZE 0x0a0c
+#define MV64x60_IDMA2MEM_2_BASE 0x0a10
+#define MV64x60_IDMA2MEM_2_SIZE 0x0a14
+#define MV64x60_IDMA2MEM_3_BASE 0x0a18
+#define MV64x60_IDMA2MEM_3_SIZE 0x0a1c
+#define MV64x60_IDMA2MEM_4_BASE 0x0a20
+#define MV64x60_IDMA2MEM_4_SIZE 0x0a24
+#define MV64x60_IDMA2MEM_5_BASE 0x0a28
+#define MV64x60_IDMA2MEM_5_SIZE 0x0a2c
+#define MV64x60_IDMA2MEM_6_BASE 0x0a30
+#define MV64x60_IDMA2MEM_6_SIZE 0x0a34
+#define MV64x60_IDMA2MEM_7_BASE 0x0a38
+#define MV64x60_IDMA2MEM_7_SIZE 0x0a3c
+#define MV64x60_IDMA2MEM_ACC_PROT_0 0x0a70
+#define MV64x60_IDMA2MEM_ACC_PROT_1 0x0a74
+#define MV64x60_IDMA2MEM_ACC_PROT_2 0x0a78
+#define MV64x60_IDMA2MEM_ACC_PROT_3 0x0a7c
+
+#define MV64x60_PCI_ACC_CNTL_WINDOWS 6
+#define MV64x60_PCI0_PCI_DECODE_CNTL 0x0d3c
+#define MV64x60_PCI1_PCI_DECODE_CNTL 0x0dbc
+
+#define MV64x60_PCI0_BAR_ENABLE 0x0c3c
+#define MV64x60_PCI02MEM_0_SIZE 0x0c08
+#define MV64x60_PCI0_ACC_CNTL_0_BASE_LO 0x1e00
+#define MV64x60_PCI0_ACC_CNTL_0_BASE_HI 0x1e04
+#define MV64x60_PCI0_ACC_CNTL_0_SIZE 0x1e08
+#define MV64x60_PCI0_ACC_CNTL_1_BASE_LO 0x1e10
+#define MV64x60_PCI0_ACC_CNTL_1_BASE_HI 0x1e14
+#define MV64x60_PCI0_ACC_CNTL_1_SIZE 0x1e18
+#define MV64x60_PCI0_ACC_CNTL_2_BASE_LO 0x1e20
+#define MV64x60_PCI0_ACC_CNTL_2_BASE_HI 0x1e24
+#define MV64x60_PCI0_ACC_CNTL_2_SIZE 0x1e28
+#define MV64x60_PCI0_ACC_CNTL_3_BASE_LO 0x1e30
+#define MV64x60_PCI0_ACC_CNTL_3_BASE_HI 0x1e34
+#define MV64x60_PCI0_ACC_CNTL_3_SIZE 0x1e38
+#define MV64x60_PCI0_ACC_CNTL_4_BASE_LO 0x1e40
+#define MV64x60_PCI0_ACC_CNTL_4_BASE_HI 0x1e44
+#define MV64x60_PCI0_ACC_CNTL_4_SIZE 0x1e48
+#define MV64x60_PCI0_ACC_CNTL_5_BASE_LO 0x1e50
+#define MV64x60_PCI0_ACC_CNTL_5_BASE_HI 0x1e54
+#define MV64x60_PCI0_ACC_CNTL_5_SIZE 0x1e58
+
+#define MV64x60_PCI1_BAR_ENABLE 0x0cbc
+#define MV64x60_PCI12MEM_0_SIZE 0x0c88
+#define MV64x60_PCI1_ACC_CNTL_0_BASE_LO 0x1e80
+#define MV64x60_PCI1_ACC_CNTL_0_BASE_HI 0x1e84
+#define MV64x60_PCI1_ACC_CNTL_0_SIZE 0x1e88
+#define MV64x60_PCI1_ACC_CNTL_1_BASE_LO 0x1e90
+#define MV64x60_PCI1_ACC_CNTL_1_BASE_HI 0x1e94
+#define MV64x60_PCI1_ACC_CNTL_1_SIZE 0x1e98
+#define MV64x60_PCI1_ACC_CNTL_2_BASE_LO 0x1ea0
+#define MV64x60_PCI1_ACC_CNTL_2_BASE_HI 0x1ea4
+#define MV64x60_PCI1_ACC_CNTL_2_SIZE 0x1ea8
+#define MV64x60_PCI1_ACC_CNTL_3_BASE_LO 0x1eb0
+#define MV64x60_PCI1_ACC_CNTL_3_BASE_HI 0x1eb4
+#define MV64x60_PCI1_ACC_CNTL_3_SIZE 0x1eb8
+#define MV64x60_PCI1_ACC_CNTL_4_BASE_LO 0x1ec0
+#define MV64x60_PCI1_ACC_CNTL_4_BASE_HI 0x1ec4
+#define MV64x60_PCI1_ACC_CNTL_4_SIZE 0x1ec8
+#define MV64x60_PCI1_ACC_CNTL_5_BASE_LO 0x1ed0
+#define MV64x60_PCI1_ACC_CNTL_5_BASE_HI 0x1ed4
+#define MV64x60_PCI1_ACC_CNTL_5_SIZE 0x1ed8
+
+#define MV64x60_CPU2PCI_SWAP_NONE 0x01000000
+
+#define MV64x60_CPU2PCI0_IO_BASE 0x0048
+#define MV64x60_CPU2PCI0_IO_SIZE 0x0050
+#define MV64x60_CPU2PCI0_IO_REMAP 0x00f0
+#define MV64x60_CPU2PCI0_MEM_0_BASE 0x0058
+#define MV64x60_CPU2PCI0_MEM_0_SIZE 0x0060
+#define MV64x60_CPU2PCI0_MEM_0_REMAP_LO 0x00f8
+#define MV64x60_CPU2PCI0_MEM_0_REMAP_HI 0x0320
+
+#define MV64x60_CPU2PCI1_IO_BASE 0x0090
+#define MV64x60_CPU2PCI1_IO_SIZE 0x0098
+#define MV64x60_CPU2PCI1_IO_REMAP 0x0108
+#define MV64x60_CPU2PCI1_MEM_0_BASE 0x00a0
+#define MV64x60_CPU2PCI1_MEM_0_SIZE 0x00a8
+#define MV64x60_CPU2PCI1_MEM_0_REMAP_LO 0x0110
+#define MV64x60_CPU2PCI1_MEM_0_REMAP_HI 0x0340
+
+struct mv64x60_mem_win {
+ u32 hi;
+ u32 lo;
+ u32 size;
+};
+
+struct mv64x60_pci_win {
+ u32 fcn;
+ u32 hi;
+ u32 lo;
+ u32 size;
+};
+
+/* PCI config access routines */
+struct {
+ u32 addr;
+ u32 data;
+} static mv64x60_pci_cfgio[2] = {
+ { /* hose 0 */
+ .addr = 0xcf8,
+ .data = 0xcfc,
+ },
+ { /* hose 1 */
+ .addr = 0xc78,
+ .data = 0xc7c,
+ }
+};
+
+u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset)
+{
+ out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
+ (1 << 31) | (bus << 16) | (devfn << 8) | offset);
+ return in_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data));
+}
+
+void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset,
+ u32 val)
+{
+ out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
+ (1 << 31) | (bus << 16) | (devfn << 8) | offset);
+ out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data), val);
+}
+
+/* I/O ctlr -> system memory setup */
+static struct mv64x60_mem_win mv64x60_cpu2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_CPU2MEM_0_BASE,
+ .size = MV64x60_CPU2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_CPU2MEM_1_BASE,
+ .size = MV64x60_CPU2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_CPU2MEM_2_BASE,
+ .size = MV64x60_CPU2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_CPU2MEM_3_BASE,
+ .size = MV64x60_CPU2MEM_3_SIZE,
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_ENET2MEM_0_BASE,
+ .size = MV64x60_ENET2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_ENET2MEM_1_BASE,
+ .size = MV64x60_ENET2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_ENET2MEM_2_BASE,
+ .size = MV64x60_ENET2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_ENET2MEM_3_BASE,
+ .size = MV64x60_ENET2MEM_3_SIZE,
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_mpsc2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_MPSC2MEM_0_BASE,
+ .size = MV64x60_MPSC2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_MPSC2MEM_1_BASE,
+ .size = MV64x60_MPSC2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_MPSC2MEM_2_BASE,
+ .size = MV64x60_MPSC2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_MPSC2MEM_3_BASE,
+ .size = MV64x60_MPSC2MEM_3_SIZE,
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_idma2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_IDMA2MEM_0_BASE,
+ .size = MV64x60_IDMA2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_IDMA2MEM_1_BASE,
+ .size = MV64x60_IDMA2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_IDMA2MEM_2_BASE,
+ .size = MV64x60_IDMA2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_IDMA2MEM_3_BASE,
+ .size = MV64x60_IDMA2MEM_3_SIZE,
+ },
+};
+
+static u32 mv64x60_dram_selects[MV64x60_CPU2MEM_WINDOWS] = {0xe,0xd,0xb,0x7};
+
+/*
+ * ENET, MPSC, and IDMA ctlrs on the MV64x60 have separate windows that
+ * must be set up so that the respective ctlr can access system memory.
+ * Configure them to be same as cpu->memory windows.
+ */
+void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
+ u8 is_coherent)
+{
+ u32 i, base, size, enables, prot = 0, snoop_bits = 0;
+
+ /* Disable ctlr->mem windows */
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0x3f);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), 0xf);
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0xff);
+
+ if (is_coherent)
+ snoop_bits = 0x2 << 12; /* Writeback */
+
+ enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
+
+ for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
+ if (enables & (1 << i)) /* Set means disabled */
+ continue;
+
+ base = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].lo))
+ << 16;
+ base |= snoop_bits | (mv64x60_dram_selects[i] << 8);
+ size = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].size))
+ << 16;
+ prot |= (0x3 << (i << 1)); /* RW access */
+
+ out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].lo), base);
+ out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].size), size);
+ out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].lo), base);
+ out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].size), size);
+ out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].lo), base);
+ out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].size), size);
+ }
+
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_0), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_1), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_2), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_0), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_1), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_0), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_1), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_2), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_3), prot);
+
+ /* Set mpsc->bridge's reg window to the bridge's internal registers. */
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2REGS_BASE),
+ (u32)bridge_pbase);
+
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), enables);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), enables);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_BAR_ENABLE), enables);
+}
+
+/* PCI MEM -> system memory, et. al. setup */
+static struct mv64x60_pci_win mv64x60_pci2mem[2] = {
+ { /* hose 0 */
+ .fcn = 0,
+ .hi = 0x14,
+ .lo = 0x10,
+ .size = MV64x60_PCI02MEM_0_SIZE,
+ },
+ { /* hose 1 */
+ .fcn = 0,
+ .hi = 0x94,
+ .lo = 0x90,
+ .size = MV64x60_PCI12MEM_0_SIZE,
+ },
+};
+
+static struct
+mv64x60_mem_win mv64x60_pci_acc[2][MV64x60_PCI_ACC_CNTL_WINDOWS] = {
+ { /* hose 0 */
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_0_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_1_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_2_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_3_SIZE,
+ },
+ },
+ { /* hose 1 */
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_0_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_1_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_2_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_3_SIZE,
+ },
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_pci2reg[2] = {
+ {
+ .hi = 0x24,
+ .lo = 0x20,
+ .size = 0,
+ },
+ {
+ .hi = 0xa4,
+ .lo = 0xa0,
+ .size = 0,
+ },
+};
+
+/* Only need to use 1 window (per hose) to get access to all of system memory */
+void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
+ u8 bus, u32 mem_size, u32 acc_bits)
+{
+ u32 i, offset, bar_enable, enables;
+
+ /* Disable all windows but PCI MEM -> Bridge's regs window */
+ enables = ~(1 << 9);
+ bar_enable = hose ? MV64x60_PCI1_BAR_ENABLE : MV64x60_PCI0_BAR_ENABLE;
+ out_le32((u32 *)(bridge_base + bar_enable), enables);
+
+ for (i=0; i<MV64x60_PCI_ACC_CNTL_WINDOWS; i++)
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][i].lo), 0);
+
+ /* If mem_size is 0, leave windows disabled */
+ if (mem_size == 0)
+ return;
+
+ /* Cause automatic updates of PCI remap regs */
+ offset = hose ?
+ MV64x60_PCI1_PCI_DECODE_CNTL : MV64x60_PCI0_PCI_DECODE_CNTL;
+ i = in_le32((u32 *)(bridge_base + offset));
+ out_le32((u32 *)(bridge_base + offset), i & ~0x1);
+
+ mem_size = (mem_size - 1) & 0xfffff000;
+
+ /* Map PCI MEM addr 0 -> System Mem addr 0 */
+ mv64x60_cfg_write(bridge_base, hose, bus,
+ PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
+ mv64x60_pci2mem[hose].hi, 0);
+ mv64x60_cfg_write(bridge_base, hose, bus,
+ PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
+ mv64x60_pci2mem[hose].lo, 0);
+ out_le32((u32 *)(bridge_base + mv64x60_pci2mem[hose].size),mem_size);
+
+ acc_bits |= MV64x60_PCI_ACC_CNTL_ENABLE;
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].hi), 0);
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].lo), acc_bits);
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].size),mem_size);
+
+ /* Set PCI MEM->bridge's reg window to where they are in CPU mem map */
+ i = (u32)bridge_base;
+ i &= 0xffff0000;
+ i |= (0x2 << 1);
+ mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
+ mv64x60_pci2reg[hose].hi, 0);
+ mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
+ mv64x60_pci2reg[hose].lo, i);
+
+ enables &= ~0x1; /* Enable PCI MEM -> System Mem window 0 */
+ out_le32((u32 *)(bridge_base + bar_enable), enables);
+}
+
+/* CPU -> PCI I/O & MEM setup */
+struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2] = {
+ { /* hose 0 */
+ .lo = MV64x60_CPU2PCI0_IO_BASE,
+ .size = MV64x60_CPU2PCI0_IO_SIZE,
+ .remap_hi = 0,
+ .remap_lo = MV64x60_CPU2PCI0_IO_REMAP,
+ },
+ { /* hose 1 */
+ .lo = MV64x60_CPU2PCI1_IO_BASE,
+ .size = MV64x60_CPU2PCI1_IO_SIZE,
+ .remap_hi = 0,
+ .remap_lo = MV64x60_CPU2PCI1_IO_REMAP,
+ },
+};
+
+struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2] = {
+ { /* hose 0 */
+ .lo = MV64x60_CPU2PCI0_MEM_0_BASE,
+ .size = MV64x60_CPU2PCI0_MEM_0_SIZE,
+ .remap_hi = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
+ .remap_lo = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
+ },
+ { /* hose 1 */
+ .lo = MV64x60_CPU2PCI1_MEM_0_BASE,
+ .size = MV64x60_CPU2PCI1_MEM_0_SIZE,
+ .remap_hi = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
+ .remap_lo = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
+ },
+};
+
+/* Only need to set up 1 window to pci mem space */
+void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
+ u32 pci_base_lo, u32 cpu_base, u32 size,
+ struct mv64x60_cpu2pci_win *offset_tbl)
+{
+ cpu_base >>= 16;
+ cpu_base |= MV64x60_CPU2PCI_SWAP_NONE;
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].lo), cpu_base);
+
+ if (offset_tbl[hose].remap_hi != 0)
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_hi),
+ pci_base_hi);
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_lo),
+ pci_base_lo >> 16);
+
+ size = (size - 1) >> 16;
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].size), size);
+}
+
+/* Read mem ctlr to get the amount of mem in system */
+u32 mv64x60_get_mem_size(u8 *bridge_base)
+{
+ u32 enables, i, v;
+ u32 mem = 0;
+
+ enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
+
+ for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
+ if (!(enables & (1<<i))) {
+ v = in_le32((u32*)(bridge_base
+ + mv64x60_cpu2mem[i].size));
+ v = ((v & 0xffff) + 1) << 16;
+ mem += v;
+ }
+
+ return mem;
+}
+
+/* Get physical address of bridge's registers */
+u8 *mv64x60_get_bridge_pbase(void)
+{
+ u32 v[2];
+ void *devp;
+
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ goto err_out;
+ if (getprop(devp, "reg", v, sizeof(v)) != sizeof(v))
+ goto err_out;
+
+ return (u8 *)v[0];
+
+err_out:
+ return 0;
+}
+
+/* Get virtual address of bridge's registers */
+u8 *mv64x60_get_bridge_base(void)
+{
+ u32 v;
+ void *devp;
+
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ goto err_out;
+ if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
+ goto err_out;
+
+ return (u8 *)v;
+
+err_out:
+ return 0;
+}
+
+u8 mv64x60_is_coherent(void)
+{
+ u32 v;
+ void *devp;
+
+ devp = finddevice("/");
+ if (devp == NULL)
+ return 1; /* Assume coherency on */
+
+ if (getprop(devp, "coherency-off", &v, sizeof(v)) < 0)
+ return 1; /* Coherency on */
+ else
+ return 0;
+}
diff --git a/arch/powerpc/boot/mv64x60.h b/arch/powerpc/boot/mv64x60.h
new file mode 100644
index 00000000000..b827105e6e5
--- /dev/null
+++ b/arch/powerpc/boot/mv64x60.h
@@ -0,0 +1,70 @@
+/*
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef _PPC_BOOT_MV64x60_H_
+#define _PPC_BOOT_MV64x60_H_
+
+#define MV64x60_CPU_BAR_ENABLE 0x0278
+
+#define MV64x60_PCI_ACC_CNTL_ENABLE (1<<0)
+#define MV64x60_PCI_ACC_CNTL_REQ64 (1<<1)
+#define MV64x60_PCI_ACC_CNTL_SNOOP_NONE 0x00000000
+#define MV64x60_PCI_ACC_CNTL_SNOOP_WT 0x00000004
+#define MV64x60_PCI_ACC_CNTL_SNOOP_WB 0x00000008
+#define MV64x60_PCI_ACC_CNTL_SNOOP_MASK 0x0000000c
+#define MV64x60_PCI_ACC_CNTL_ACCPROT (1<<4)
+#define MV64x60_PCI_ACC_CNTL_WRPROT (1<<5)
+#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE 0x00000000
+#define MV64x60_PCI_ACC_CNTL_SWAP_NONE 0x00000040
+#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE_WORD 0x00000080
+#define MV64x60_PCI_ACC_CNTL_SWAP_WORD 0x000000c0
+#define MV64x60_PCI_ACC_CNTL_SWAP_MASK 0x000000c0
+#define MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES 0x00000000
+#define MV64x60_PCI_ACC_CNTL_MBURST_64_BYTES 0x00000100
+#define MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES 0x00000200
+#define MV64x60_PCI_ACC_CNTL_MBURST_MASK 0x00000300
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES 0x00000000
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_64_BYTES 0x00000400
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_128_BYTES 0x00000800
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES 0x00000c00
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_MASK 0x00000c00
+
+struct mv64x60_cpu2pci_win {
+ u32 lo;
+ u32 size;
+ u32 remap_hi;
+ u32 remap_lo;
+};
+
+extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2];
+extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2];
+
+u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
+ u8 offset);
+void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
+ u8 offset, u32 val);
+
+void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
+ u8 is_coherent);
+void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
+ u8 bus, u32 mem_size, u32 acc_bits);
+void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
+ u32 pci_base_lo, u32 cpu_base, u32 size,
+ struct mv64x60_cpu2pci_win *offset_tbl);
+u32 mv64x60_get_mem_size(u8 *bridge_base);
+u8 *mv64x60_get_bridge_pbase(void);
+u8 *mv64x60_get_bridge_base(void);
+u8 mv64x60_is_coherent(void);
+
+int mv64x60_i2c_open(void);
+int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
+ u32 count);
+void mv64x60_i2c_close(void);
+
+#endif /* _PPC_BOOT_MV64x60_H_ */
diff --git a/arch/powerpc/boot/mv64x60_i2c.c b/arch/powerpc/boot/mv64x60_i2c.c
new file mode 100644
index 00000000000..435fe852868
--- /dev/null
+++ b/arch/powerpc/boot/mv64x60_i2c.c
@@ -0,0 +1,206 @@
+/*
+ * Bootloader version of the i2c driver for the MV64x60.
+ *
+ * Author: Dale Farnsworth <dfarnsworth@mvista.com>
+ * Maintained by: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2003, 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express or
+ * implied.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+#include "mv64x60.h"
+
+extern void udelay(long);
+
+/* Register defines */
+#define MV64x60_I2C_REG_SLAVE_ADDR 0x00
+#define MV64x60_I2C_REG_DATA 0x04
+#define MV64x60_I2C_REG_CONTROL 0x08
+#define MV64x60_I2C_REG_STATUS 0x0c
+#define MV64x60_I2C_REG_BAUD 0x0c
+#define MV64x60_I2C_REG_EXT_SLAVE_ADDR 0x10
+#define MV64x60_I2C_REG_SOFT_RESET 0x1c
+
+#define MV64x60_I2C_CONTROL_ACK 0x04
+#define MV64x60_I2C_CONTROL_IFLG 0x08
+#define MV64x60_I2C_CONTROL_STOP 0x10
+#define MV64x60_I2C_CONTROL_START 0x20
+#define MV64x60_I2C_CONTROL_TWSIEN 0x40
+#define MV64x60_I2C_CONTROL_INTEN 0x80
+
+#define MV64x60_I2C_STATUS_BUS_ERR 0x00
+#define MV64x60_I2C_STATUS_MAST_START 0x08
+#define MV64x60_I2C_STATUS_MAST_REPEAT_START 0x10
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
+#define MV64x60_I2C_STATUS_MAST_WR_ACK 0x28
+#define MV64x60_I2C_STATUS_MAST_WR_NO_ACK 0x30
+#define MV64x60_I2C_STATUS_MAST_LOST_ARB 0x38
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
+#define MV64x60_I2C_STATUS_MAST_RD_DATA_ACK 0x50
+#define MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
+#define MV64x60_I2C_STATUS_NO_STATUS 0xf8
+
+static u8 *ctlr_base;
+
+static int mv64x60_i2c_wait_for_status(int wanted)
+{
+ int i;
+ int status;
+
+ for (i=0; i<1000; i++) {
+ udelay(10);
+ status = in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_STATUS))
+ & 0xff;
+ if (status == wanted)
+ return status;
+ }
+ return -status;
+}
+
+static int mv64x60_i2c_control(int control, int status)
+{
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
+ return mv64x60_i2c_wait_for_status(status);
+}
+
+static int mv64x60_i2c_read_byte(int control, int status)
+{
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
+ if (mv64x60_i2c_wait_for_status(status) < 0)
+ return -1;
+ return in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA)) & 0xff;
+}
+
+static int mv64x60_i2c_write_byte(int data, int control, int status)
+{
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA), data & 0xff);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
+ return mv64x60_i2c_wait_for_status(status);
+}
+
+int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
+ u32 count)
+{
+ int i;
+ int data;
+ int control;
+ int status;
+
+ if (ctlr_base == NULL)
+ return -1;
+
+ /* send reset */
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SOFT_RESET), 0);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SLAVE_ADDR), 0);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_EXT_SLAVE_ADDR), 0);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_BAUD), (4 << 3) | 0x4);
+
+ if (mv64x60_i2c_control(MV64x60_I2C_CONTROL_TWSIEN,
+ MV64x60_I2C_STATUS_NO_STATUS) < 0)
+ return -1;
+
+ /* send start */
+ control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_START;
+ if (mv64x60_i2c_control(control, status) < 0)
+ return -1;
+
+ /* select device for writing */
+ data = devaddr & ~0x1;
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK;
+ if (mv64x60_i2c_write_byte(data, control, status) < 0)
+ return -1;
+
+ /* send offset of data */
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_WR_ACK;
+ if (offset_size > 1) {
+ if (mv64x60_i2c_write_byte(offset >> 8, control, status) < 0)
+ return -1;
+ }
+ if (mv64x60_i2c_write_byte(offset, control, status) < 0)
+ return -1;
+
+ /* resend start */
+ control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_REPEAT_START;
+ if (mv64x60_i2c_control(control, status) < 0)
+ return -1;
+
+ /* select device for reading */
+ data = devaddr | 0x1;
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK;
+ if (mv64x60_i2c_write_byte(data, control, status) < 0)
+ return -1;
+
+ /* read all but last byte of data */
+ control = MV64x60_I2C_CONTROL_ACK | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_RD_DATA_ACK;
+
+ for (i=1; i<count; i++) {
+ data = mv64x60_i2c_read_byte(control, status);
+ if (data < 0) {
+ printf("errors on iteration %d\n", i);
+ return -1;
+ }
+ *buf++ = data;
+ }
+
+ /* read last byte of data */
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK;
+ data = mv64x60_i2c_read_byte(control, status);
+ if (data < 0)
+ return -1;
+ *buf++ = data;
+
+ /* send stop */
+ control = MV64x60_I2C_CONTROL_STOP | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_NO_STATUS;
+ if (mv64x60_i2c_control(control, status) < 0)
+ return -1;
+
+ return count;
+}
+
+int mv64x60_i2c_open(void)
+{
+ u32 v;
+ void *devp;
+
+ devp = finddevice("/mv64x60/i2c");
+ if (devp == NULL)
+ goto err_out;
+ if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
+ goto err_out;
+
+ ctlr_base = (u8 *)v;
+ return 0;
+
+err_out:
+ return -1;
+}
+
+void mv64x60_i2c_close(void)
+{
+ ctlr_base = NULL;
+}
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 73bd47a3a07..959124f3f9a 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -79,6 +79,7 @@ void start(void);
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
+int mpsc_console_init(void *devp, struct serial_console_data *scdp);
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
extern void flush_cache(void *, unsigned long);
diff --git a/arch/powerpc/boot/prpmc2800.c b/arch/powerpc/boot/prpmc2800.c
new file mode 100644
index 00000000000..f428bac10d4
--- /dev/null
+++ b/arch/powerpc/boot/prpmc2800.c
@@ -0,0 +1,577 @@
+/*
+ * Motorola ECC prpmc280/f101 & prpmc2800/f101e platform code.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+#include "gunzip_util.h"
+#include "mv64x60.h"
+
+extern char _end[];
+extern char _vmlinux_start[], _vmlinux_end[];
+extern char _dtb_start[], _dtb_end[];
+
+extern void udelay(long delay);
+
+#define KB 1024U
+#define MB (KB*KB)
+#define GB (KB*MB)
+#define MHz (1000U*1000U)
+#define GHz (1000U*MHz)
+
+#define BOARD_MODEL "PrPMC2800"
+#define BOARD_MODEL_MAX 32 /* max strlen(BOARD_MODEL) + 1 */
+
+#define EEPROM2_ADDR 0xa4
+#define EEPROM3_ADDR 0xa8
+
+BSS_STACK(16*KB);
+
+static u8 *bridge_base;
+
+typedef enum {
+ BOARD_MODEL_PRPMC280,
+ BOARD_MODEL_PRPMC2800,
+} prpmc2800_board_model;
+
+typedef enum {
+ BRIDGE_TYPE_MV64360,
+ BRIDGE_TYPE_MV64362,
+} prpmc2800_bridge_type;
+
+struct prpmc2800_board_info {
+ prpmc2800_board_model model;
+ char variant;
+ prpmc2800_bridge_type bridge_type;
+ u8 subsys0;
+ u8 subsys1;
+ u8 vpd4;
+ u8 vpd4_mask;
+ u32 core_speed;
+ u32 mem_size;
+ u32 boot_flash;
+ u32 user_flash;
+};
+
+static struct prpmc2800_board_info prpmc2800_board_info[] = {
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'a',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'b',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x01,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 0,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'c',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x02,
+ .vpd4_mask = 0x0f,
+ .core_speed = 733*MHz,
+ .mem_size = 512*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'd',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x03,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 1*GB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'e',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x04,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'f',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x05,
+ .vpd4_mask = 0x0f,
+ .core_speed = 733*MHz,
+ .mem_size = 128*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'g',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x06,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 256*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'h',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x07,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 1*GB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'a',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8c,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'b',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8d,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 0,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'c',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8e,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 733*MHz,
+ .mem_size = 512*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'd',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8f,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 1*GB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'e',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8a,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'f',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8b,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 733*MHz,
+ .mem_size = 128*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'g',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8c,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 2*GB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'h',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8d,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 733*MHz,
+ .mem_size = 1*GB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+};
+
+static struct prpmc2800_board_info *prpmc2800_get_board_info(u8 *vpd)
+{
+ struct prpmc2800_board_info *bip;
+ int i;
+
+ for (i=0,bip=prpmc2800_board_info; i<ARRAY_SIZE(prpmc2800_board_info);
+ i++,bip++)
+ if ((vpd[0] == bip->subsys0) && (vpd[1] == bip->subsys1)
+ && ((vpd[4] & bip->vpd4_mask) == bip->vpd4))
+ return bip;
+
+ return NULL;
+}
+
+/* Get VPD from i2c eeprom 2, then match it to a board info entry */
+static struct prpmc2800_board_info *prpmc2800_get_bip(void)
+{
+ struct prpmc2800_board_info *bip;
+ u8 vpd[5];
+ int rc;
+
+ if (mv64x60_i2c_open())
+ fatal("Error: Can't open i2c device\n\r");
+
+ /* Get VPD from i2c eeprom-2 */
+ memset(vpd, 0, sizeof(vpd));
+ rc = mv64x60_i2c_read(EEPROM2_ADDR, vpd, 0x1fde, 2, sizeof(vpd));
+ if (rc < 0)
+ fatal("Error: Couldn't read eeprom2\n\r");
+ mv64x60_i2c_close();
+
+ /* Get board type & related info */
+ bip = prpmc2800_get_board_info(vpd);
+ if (bip == NULL) {
+ printf("Error: Unsupported board or corrupted VPD:\n\r");
+ printf(" 0x%x 0x%x 0x%x 0x%x 0x%x\n\r",
+ vpd[0], vpd[1], vpd[2], vpd[3], vpd[4]);
+ printf("Using device tree defaults...\n\r");
+ }
+
+ return bip;
+}
+
+static void prpmc2800_bridge_setup(u32 mem_size)
+{
+ u32 i, v[12], enables, acc_bits;
+ u32 pci_base_hi, pci_base_lo, size, buf[2];
+ unsigned long cpu_base;
+ int rc;
+ void *devp;
+ u8 *bridge_pbase, is_coherent;
+ struct mv64x60_cpu2pci_win *tbl;
+
+ bridge_pbase = mv64x60_get_bridge_pbase();
+ is_coherent = mv64x60_is_coherent();
+
+ if (is_coherent)
+ acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
+ | MV64x60_PCI_ACC_CNTL_SWAP_NONE
+ | MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
+ | MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
+ else
+ acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
+ | MV64x60_PCI_ACC_CNTL_SWAP_NONE
+ | MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
+ | MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
+
+ mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
+ mv64x60_config_pci_windows(bridge_base, bridge_pbase, 0, 0, mem_size,
+ acc_bits);
+
+ /* Get the cpu -> pci i/o & mem mappings from the device tree */
+ devp = finddevice("/mv64x60/pci@80000000");
+ if (devp == NULL)
+ fatal("Error: Missing /mv64x60/pci@80000000"
+ " device tree node\n\r");
+
+ rc = getprop(devp, "ranges", v, sizeof(v));
+ if (rc != sizeof(v))
+ fatal("Error: Can't find /mv64x60/pci@80000000/ranges"
+ " property\n\r");
+
+ /* Get the cpu -> pci i/o & mem mappings from the device tree */
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ fatal("Error: Missing /mv64x60 device tree node\n\r");
+
+ enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
+ enables |= 0x0007fe00; /* Disable all cpu->pci windows */
+ out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
+
+ for (i=0; i<12; i+=6) {
+ switch (v[i] & 0xff000000) {
+ case 0x01000000: /* PCI I/O Space */
+ tbl = mv64x60_cpu2pci_io;
+ break;
+ case 0x02000000: /* PCI MEM Space */
+ tbl = mv64x60_cpu2pci_mem;
+ break;
+ default:
+ continue;
+ }
+
+ pci_base_hi = v[i+1];
+ pci_base_lo = v[i+2];
+ cpu_base = v[i+3];
+ size = v[i+5];
+
+ buf[0] = cpu_base;
+ buf[1] = size;
+
+ if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base))
+ fatal("Error: Can't translate PCI address 0x%x\n\r",
+ (u32)cpu_base);
+
+ mv64x60_config_cpu2pci_window(bridge_base, 0, pci_base_hi,
+ pci_base_lo, cpu_base, size, tbl);
+ }
+
+ enables &= ~0x00000600; /* Enable cpu->pci0 i/o, cpu->pci0 mem0 */
+ out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
+}
+
+static void prpmc2800_fixups(void)
+{
+ u32 v[2], l, mem_size;
+ int rc;
+ void *devp;
+ char model[BOARD_MODEL_MAX];
+ struct prpmc2800_board_info *bip;
+
+ bip = prpmc2800_get_bip(); /* Get board info based on VPD */
+
+ mem_size = (bip) ? bip->mem_size : mv64x60_get_mem_size(bridge_base);
+ prpmc2800_bridge_setup(mem_size); /* Do necessary bridge setup */
+
+ /* If the VPD doesn't match what we know about, just use the
+ * defaults already in the device tree.
+ */
+ if (!bip)
+ return;
+
+ /* Know the board type so override device tree defaults */
+ /* Set /model appropriately */
+ devp = finddevice("/");
+ if (devp == NULL)
+ fatal("Error: Missing '/' device tree node\n\r");
+ memset(model, 0, BOARD_MODEL_MAX);
+ strncpy(model, BOARD_MODEL, BOARD_MODEL_MAX - 2);
+ l = strlen(model);
+ if (bip->model == BOARD_MODEL_PRPMC280)
+ l--;
+ model[l++] = bip->variant;
+ model[l++] = '\0';
+ setprop(devp, "model", model, l);
+
+ /* Set /cpus/PowerPC,7447/clock-frequency */
+ devp = finddevice("/cpus/PowerPC,7447");
+ if (devp == NULL)
+ fatal("Error: Missing proper /cpus device tree node\n\r");
+ v[0] = bip->core_speed;
+ setprop(devp, "clock-frequency", &v[0], sizeof(v[0]));
+
+ /* Set /memory/reg size */
+ devp = finddevice("/memory");
+ if (devp == NULL)
+ fatal("Error: Missing /memory device tree node\n\r");
+ v[0] = 0;
+ v[1] = bip->mem_size;
+ setprop(devp, "reg", v, sizeof(v));
+
+ /* Update /mv64x60/model, if this is a mv64362 */
+ if (bip->bridge_type == BRIDGE_TYPE_MV64362) {
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ fatal("Error: Missing /mv64x60 device tree node\n\r");
+ setprop(devp, "model", "mv64362", strlen("mv64362") + 1);
+ }
+
+ /* Set User FLASH size */
+ devp = finddevice("/mv64x60/flash@a0000000");
+ if (devp == NULL)
+ fatal("Error: Missing User FLASH device tree node\n\r");
+ rc = getprop(devp, "reg", v, sizeof(v));
+ if (rc != sizeof(v))
+ fatal("Error: Can't find User FLASH reg property\n\r");
+ v[1] = bip->user_flash;
+ setprop(devp, "reg", v, sizeof(v));
+}
+
+#define MV64x60_MPP_CNTL_0 0xf000
+#define MV64x60_MPP_CNTL_2 0xf008
+#define MV64x60_GPP_IO_CNTL 0xf100
+#define MV64x60_GPP_LEVEL_CNTL 0xf110
+#define MV64x60_GPP_VALUE_SET 0xf118
+
+static void prpmc2800_reset(void)
+{
+ u32 temp;
+
+ udelay(5000000);
+
+ if (bridge_base != 0) {
+ temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
+ temp &= 0xFFFF0FFF;
+ out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
+ temp |= 0x00000004;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
+ temp |= 0x00000004;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
+ temp &= 0xFFFF0FFF;
+ out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
+ temp |= 0x00080000;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
+ temp |= 0x00080000;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
+
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
+ 0x00080004);
+ }
+
+ for (;;);
+}
+
+#define HEAP_SIZE (16*MB)
+static struct gunzip_state gzstate;
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ struct elf_info ei;
+ char *heap_start, *dtb;
+ int dt_size = _dtb_end - _dtb_start;
+ void *vmlinuz_addr = _vmlinux_start;
+ unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start;
+ char elfheader[256];
+
+ if (dt_size <= 0) /* No fdt */
+ exit();
+
+ /*
+ * Start heap after end of the kernel (after decompressed to
+ * address 0) or the end of the zImage, whichever is higher.
+ * That's so things allocated by simple_alloc won't overwrite
+ * any part of the zImage and the kernel won't overwrite the dtb
+ * when decompressed & relocated.
+ */
+ gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
+ gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
+
+ if (!parse_elf32(elfheader, &ei))
+ exit();
+
+ heap_start = (char *)(ei.memsize + ei.elfoffset); /* end of kernel*/
+ heap_start = max(heap_start, (char *)_end); /* end of zImage */
+
+ if ((unsigned)simple_alloc_init(heap_start, HEAP_SIZE, 2*KB, 16)
+ > (128*MB))
+ exit();
+
+ /* Relocate dtb to safe area past end of zImage & kernel */
+ dtb = malloc(dt_size);
+ if (!dtb)
+ exit();
+ memmove(dtb, _dtb_start, dt_size);
+ if (ft_init(dtb, dt_size, 16))
+ exit();
+
+ bridge_base = mv64x60_get_bridge_base();
+
+ platform_ops.fixups = prpmc2800_fixups;
+ platform_ops.exit = prpmc2800_reset;
+
+ if (serial_console_init() < 0)
+ exit();
+}
+
+/* _zimage_start called very early--need to turn off external interrupts */
+asm (" .globl _zimage_start\n\
+ _zimage_start:\n\
+ mfmsr 10\n\
+ rlwinm 10,10,0,~(1<<15) /* Clear MSR_EE */\n\
+ sync\n\
+ mtmsr 10\n\
+ isync\n\
+ b _zimage_start_lib\n\
+");
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index e8de4cf59be..7fd32330a9a 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -125,6 +125,8 @@ int serial_console_init(void)
if (!strcmp(compat, "ns16550"))
rc = ns16550_console_init(devp, &serial_cd);
+ else if (!strcmp(compat, "marvell,mpsc"))
+ rc = mpsc_console_init(devp, &serial_cd);
/* Add other serial console driver calls here */
diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig
new file mode 100644
index 00000000000..c70a7308200
--- /dev/null
+++ b/arch/powerpc/configs/prpmc2800_defconfig
@@ -0,0 +1,1442 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Wed May 9 09:42:46 2007
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_CONFIG_CHECK_CACHE_COHERENCY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+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_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+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=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_APUS is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_LINKSTATION is not set
+# CONFIG_MPC7448HPC2 is not set
+# CONFIG_PPC_HOLLY is not set
+CONFIG_PPC_PRPMC2800=y
+CONFIG_MV64X60=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_CPM2 is not set
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_WANT_DEVICE_TREE=y
+CONFIG_DEVICE_TREE="prpmc2800.dts"
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+# CONFIG_PPC_INDIRECT_PCI_BE is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# 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
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# 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
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# 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
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_PHANTOM 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=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# 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_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# 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
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+CONFIG_SATA_MV=y
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+CONFIG_MACINTOSH_DRIVERS=y
+# CONFIG_MAC_EMUMOUSEBTN is not set
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# 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 is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# 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
+CONFIG_MV643XX_ETH=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# 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
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# 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
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE 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
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MPSC=y
+CONFIG_SERIAL_MPSC_CONSOLE=y
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+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_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP 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=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+CONFIG_I2C_MV64XXX=y
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 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_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 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_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG 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
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# 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=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL 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
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+CONFIG_RTC_DRV_MAX6900=y
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# 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
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index fd604968f9a..477934558f0 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.21
-# Mon Apr 30 12:03:35 2007
+# Fri May 11 10:16:27 2007
#
CONFIG_PPC64=y
CONFIG_64BIT=y
@@ -40,6 +40,7 @@ CONFIG_PPC_FPU=y
# CONFIG_PPC_OF_PLATFORM_PCI is not set
CONFIG_ALTIVEC=y
CONFIG_PPC_STD_MMU=y
+# CONFIG_PPC_MM_SLICES is not set
CONFIG_VIRT_CPU_ACCOUNTING=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
@@ -67,6 +68,7 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
# CONFIG_CPUSETS is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
@@ -87,12 +89,13 @@ CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
#
# Loadable module support
@@ -213,6 +216,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_ARCH_MEMORY_PROBE=y
+# CONFIG_PPC_HAS_HASH_64K is not set
# CONFIG_PPC_64K_PAGES is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PROC_DEVICETREE=y
@@ -229,15 +233,12 @@ CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
CONFIG_KERNEL_START=0xc000000000000000
#
@@ -363,7 +364,9 @@ CONFIG_BT_HCIUSB_SCO=y
#
# CONFIG_CFG80211 is not set
CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
#
# Device Drivers
@@ -414,6 +417,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
#
# Misc devices
#
+# CONFIG_BLINK is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -447,6 +451,7 @@ 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
@@ -473,25 +478,7 @@ CONFIG_CHR_DEV_SG=m
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Macintosh device drivers
-#
-# CONFIG_MAC_EMUMOUSEBTN is not set
-# CONFIG_WINDFARM is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
#
# Network device support
@@ -519,6 +506,7 @@ CONFIG_MII=m
#
# Ethernet (10000 Mbit)
#
+CONFIG_MLX4_DEBUG=y
#
# Token Ring devices
@@ -531,6 +519,25 @@ CONFIG_MII=m
# CONFIG_WLAN_80211 is not set
#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+CONFIG_USB_PEGASUS=m
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET_MII=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDCETHER is not set
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+CONFIG_USB_NET_MCS7830=m
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+
+#
# Wan interfaces
#
# CONFIG_WAN is not set
@@ -575,6 +582,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE 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
@@ -609,15 +617,10 @@ CONFIG_LEGACY_PTY_COUNT=16
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set
@@ -626,10 +629,6 @@ CONFIG_GEN_RTC=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
# CONFIG_I2C is not set
#
@@ -642,12 +641,7 @@ CONFIG_GEN_RTC=y
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
#
# Multifunction device drivers
@@ -669,12 +663,23 @@ CONFIG_GEN_RTC=y
# Graphics support
#
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
@@ -702,10 +707,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
@@ -768,6 +769,20 @@ CONFIG_HID=y
# CONFIG_HID_DEBUG 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
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -827,56 +842,10 @@ CONFIG_USB_STORAGE=m
# 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=m
-# CONFIG_USB_RTL8150 is not set
-CONFIG_USB_USBNET_MII=m
-CONFIG_USB_USBNET=m
-# CONFIG_USB_NET_CDCETHER is not set
-# CONFIG_USB_NET_DM9601 is not set
-# CONFIG_USB_NET_GL620A is not set
-# CONFIG_USB_NET_NET1080 is not set
-# CONFIG_USB_NET_PLUSB is not set
-CONFIG_USB_NET_MCS7830=m
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-# CONFIG_USB_NET_ZAURUS is not set
CONFIG_USB_MON=y
#
@@ -920,10 +889,6 @@ CONFIG_USB_MON=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
#
@@ -966,14 +931,6 @@ CONFIG_USB_MON=y
#
#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
# File systems
#
CONFIG_EXT2_FS=m
@@ -1071,6 +1028,7 @@ CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1148,11 +1106,13 @@ CONFIG_NLS_ISO8859_1=y
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_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
#
# Instrumentation Support
@@ -1171,7 +1131,6 @@ CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
@@ -1205,6 +1164,7 @@ CONFIG_PPC_EARLY_DEBUG=y
# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
+# CONFIG_PPC_EARLY_DEBUG_44x is not set
#
# Security options
@@ -1234,6 +1194,7 @@ CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/powerpc/kernel/audit.c b/arch/powerpc/kernel/audit.c
index 7fe5e6300e9..a4dab7cab34 100644
--- a/arch/powerpc/kernel/audit.c
+++ b/arch/powerpc/kernel/audit.c
@@ -23,6 +23,20 @@ static unsigned chattr_class[] = {
~0U
};
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+#ifdef CONFIG_PPC64
+ if (arch == AUDIT_ARCH_PPC)
+ return 1;
+#endif
+ return 0;
+}
+
int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_PPC64
@@ -51,15 +65,18 @@ static int __init audit_classes_init(void)
extern __u32 ppc32_write_class[];
extern __u32 ppc32_read_class[];
extern __u32 ppc32_chattr_class[];
+ extern __u32 ppc32_signal_class[];
audit_register_class(AUDIT_CLASS_WRITE_32, ppc32_write_class);
audit_register_class(AUDIT_CLASS_READ_32, ppc32_read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ppc32_dir_class);
audit_register_class(AUDIT_CLASS_CHATTR_32, ppc32_chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL_32, ppc32_signal_class);
#endif
audit_register_class(AUDIT_CLASS_WRITE, write_class);
audit_register_class(AUDIT_CLASS_READ, read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
return 0;
}
diff --git a/arch/powerpc/kernel/compat_audit.c b/arch/powerpc/kernel/compat_audit.c
index 640d4bb2932..108ff14e212 100644
--- a/arch/powerpc/kernel/compat_audit.c
+++ b/arch/powerpc/kernel/compat_audit.c
@@ -21,6 +21,11 @@ unsigned ppc32_read_class[] = {
~0U
};
+unsigned ppc32_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
int ppc32_classify_syscall(unsigned syscall)
{
switch(syscall) {
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 9ed4931af16..068377a2a8d 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -173,7 +173,7 @@ void local_irq_restore(unsigned long en)
lv1_get_version_info(&tmp);
}
- hard_irq_enable();
+ __hard_irq_enable();
}
#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index b5c96af955c..3786dcc8a7b 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -24,7 +24,7 @@
/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
- (ns) > 0)
+ (ns) >= 0)
static struct of_bus *of_match_bus(struct device_node *np);
static int __of_address_to_resource(struct device_node *dev,
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 370803722e4..ed07a198f8d 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -530,3 +530,44 @@ void __init setup_panic(void)
{
atomic_notifier_chain_register(&panic_notifier_list, &ppc_panic_block);
}
+
+#ifdef CONFIG_CHECK_CACHE_COHERENCY
+/*
+ * For platforms that have configurable cache-coherency. This function
+ * checks that the cache coherency setting of the kernel matches the setting
+ * left by the firmware, as indicated in the device tree. Since a mismatch
+ * will eventually result in DMA failures, we print * and error and call
+ * BUG() in that case.
+ */
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define KERNEL_COHERENCY 0
+#else
+#define KERNEL_COHERENCY 1
+#endif
+
+static int __init check_cache_coherency(void)
+{
+ struct device_node *np;
+ const void *prop;
+ int devtree_coherency;
+
+ np = of_find_node_by_path("/");
+ prop = of_get_property(np, "coherency-off", NULL);
+ of_node_put(np);
+
+ devtree_coherency = prop ? 0 : 1;
+
+ if (devtree_coherency != KERNEL_COHERENCY) {
+ printk(KERN_ERR
+ "kernel coherency:%s != device tree_coherency:%s\n",
+ KERNEL_COHERENCY ? "on" : "off",
+ devtree_coherency ? "on" : "off");
+ BUG();
+ }
+
+ return 0;
+}
+
+late_initcall(check_cache_coherency);
+#endif /* CONFIG_CHECK_CACHE_COHERENCY */
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
index 064a7ba4f02..77b7b34b595 100644
--- a/arch/powerpc/kernel/swsusp.c
+++ b/arch/powerpc/kernel/swsusp.c
@@ -36,8 +36,4 @@ void restore_processor_state(void)
#ifdef CONFIG_PPC32
set_context(current->active_mm->context.id, current->active_mm->pgd);
#endif
-
-#ifdef CONFIG_PPC64
- hard_irq_enable();
-#endif
}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 7cedef8f5f7..2c8564d54e4 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -711,30 +711,15 @@ void wakeup_decrementer(void)
void __init smp_space_timers(unsigned int max_cpus)
{
int i;
- unsigned long half = tb_ticks_per_jiffy / 2;
- unsigned long offset = tb_ticks_per_jiffy / max_cpus;
u64 previous_tb = per_cpu(last_jiffy, boot_cpuid);
/* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
previous_tb -= tb_ticks_per_jiffy;
- /*
- * The stolen time calculation for POWER5 shared-processor LPAR
- * systems works better if the two threads' timebase interrupts
- * are staggered by half a jiffy with respect to each other.
- */
+
for_each_possible_cpu(i) {
if (i == boot_cpuid)
continue;
- if (i == (boot_cpuid ^ 1))
- per_cpu(last_jiffy, i) =
- per_cpu(last_jiffy, boot_cpuid) - half;
- else if (i & 1)
- per_cpu(last_jiffy, i) =
- per_cpu(last_jiffy, i ^ 1) + half;
- else {
- previous_tb += offset;
- per_cpu(last_jiffy, i) = previous_tb;
- }
+ per_cpu(last_jiffy, i) = previous_tb;
}
}
#endif
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 7d722eea4ea..4a20d890e2f 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -351,7 +351,7 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot,
unsigned long hpte_r = hpte->r;
unsigned long hpte_v = hpte->v;
unsigned long avpn;
- int i, size, shift, penc, avpnm_bits;
+ int i, size, shift, penc;
if (!(hpte_v & HPTE_V_LARGE))
size = MMU_PAGE_4K;
@@ -395,7 +395,7 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot,
vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask;
break;
default:
- avpn = vpi = psize = 0;
+ avpn = vpi = size = 0;
}
avpn |= (vpi << mmu_psize_defs[size].shift);
}
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index 8c20f0fb865..812bf563ed6 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -43,12 +43,10 @@ static void cbe_power_save(void)
unsigned long ctrl, thread_switch_control;
/*
- * We need to hard disable interrupts, but we also need to mark them
- * hard disabled in the PACA so that the local_irq_enable() done by
- * our caller upon return propertly hard enables.
+ * We need to hard disable interrupts, the local_irq_enable() done by
+ * our caller upon return will hard re-enable.
*/
hard_irq_disable();
- get_paca()->hard_enabled = 0;
ctrl = mfspr(SPRN_CTRLF);
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 8f3c2a73e16..f2d26268ca6 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -31,6 +31,14 @@ config PPC_HOLLY
help
Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
Board with TSI108/9 bridge (Hickory/Holly)
+
+config PPC_PRPMC2800
+ bool "Motorola-PrPMC2800"
+ select MV64X60
+ select NOT_COHERENT_CACHE
+ select WANT_DEVICE_TREE
+ help
+ This option enables support for the Motorola PrPMC2800 board
endchoice
config TSI108_BRIDGE
@@ -46,6 +54,11 @@ config MPC10X_BRIDGE
select PPC_INDIRECT_PCI
default y
+config MV64X60
+ bool
+ select PPC_INDIRECT_PCI
+ select CONFIG_CHECK_CACHE_COHERENCY
+
config MPC10X_OPENPIC
bool
depends on LINKSTATION
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
index b39fe4f470d..844947cfc5d 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -4,3 +4,4 @@
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
obj-$(CONFIG_PPC_HOLLY) += holly.o
+obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o
diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
new file mode 100644
index 00000000000..53420951dc5
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
@@ -0,0 +1,171 @@
+/*
+ * Board setup routines for the Motorola PrPMC2800
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/kexec.h>
+
+#include <mm/mmu_decl.h>
+
+#include <sysdev/mv64x60.h>
+
+#define MV64x60_MPP_CNTL_0 0x0000
+#define MV64x60_MPP_CNTL_2 0x0008
+
+#define MV64x60_GPP_IO_CNTL 0x0000
+#define MV64x60_GPP_LEVEL_CNTL 0x0010
+#define MV64x60_GPP_VALUE_SET 0x0018
+
+#define PLATFORM_NAME_MAX 32
+
+static char prpmc2800_platform_name[PLATFORM_NAME_MAX];
+
+static void __iomem *mv64x60_mpp_reg_base;
+static void __iomem *mv64x60_gpp_reg_base;
+
+static void __init prpmc2800_setup_arch(void)
+{
+ struct device_node *np;
+ phys_addr_t paddr;
+ const unsigned int *reg;
+ const unsigned int *prop;
+
+ /*
+ * ioremap mpp and gpp registers in case they are later
+ * needed by prpmc2800_reset_board().
+ */
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-mpp");
+ reg = of_get_property(np, "reg", NULL);
+ paddr = of_translate_address(np, reg);
+ of_node_put(np);
+ mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
+
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-gpp");
+ reg = of_get_property(np, "reg", NULL);
+ paddr = of_translate_address(np, reg);
+ of_node_put(np);
+ mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
+
+ np = of_find_node_by_type(NULL, "cpu");
+ prop = of_get_property(np, "clock-frequency", NULL);
+ if (prop)
+ loops_per_jiffy = *prop / HZ;
+ of_node_put(np);
+
+#ifdef CONFIG_PCI
+ mv64x60_pci_init();
+#endif
+
+ printk("Motorola %s\n", prpmc2800_platform_name);
+}
+
+static void prpmc2800_reset_board(void)
+{
+ u32 temp;
+
+ local_irq_disable();
+
+ temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
+ temp &= 0xFFFF0FFF;
+ out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
+ temp |= 0x00000004;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
+ temp |= 0x00000004;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
+
+ temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
+ temp &= 0xFFFF0FFF;
+ out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
+ temp |= 0x00080000;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
+ temp |= 0x00080000;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
+
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
+}
+
+static void prpmc2800_restart(char *cmd)
+{
+ volatile ulong i = 10000000;
+
+ prpmc2800_reset_board();
+
+ while (i-- > 0);
+ panic("restart failed\n");
+}
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define PPRPM2800_COHERENCY_SETTING "off"
+#else
+#define PPRPM2800_COHERENCY_SETTING "on"
+#endif
+
+void prpmc2800_show_cpuinfo(struct seq_file *m)
+{
+ uint memsize = total_memory;
+
+ seq_printf(m, "Vendor\t\t: Motorola\n");
+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+ seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING);
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init prpmc2800_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+ unsigned long len = PLATFORM_NAME_MAX;
+ void *m;
+
+ if (!of_flat_dt_is_compatible(root, "motorola,PrPMC2800"))
+ return 0;
+
+ /* Update ppc_md.name with name from dt */
+ m = of_get_flat_dt_prop(root, "model", &len);
+ if (m)
+ strncpy(prpmc2800_platform_name, m,
+ min((int)len, PLATFORM_NAME_MAX - 1));
+
+ return 1;
+}
+
+define_machine(prpmc2800){
+ .name = prpmc2800_platform_name,
+ .probe = prpmc2800_probe,
+ .setup_arch = prpmc2800_setup_arch,
+ .show_cpuinfo = prpmc2800_show_cpuinfo,
+ .init_IRQ = mv64x60_init_irq,
+ .get_irq = mv64x60_get_irq,
+ .restart = prpmc2800_restart,
+ .calibrate_decr = generic_calibrate_decr,
+#ifdef CONFIG_KEXEC
+ .machine_kexec = default_machine_kexec,
+ .machine_kexec_prepare = default_machine_kexec_prepare,
+ .machine_crash_shutdown = default_machine_crash_shutdown,
+#endif
+};
diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c
index 5985ce0c5c4..03cd45d8fef 100644
--- a/arch/powerpc/platforms/pasemi/idle.c
+++ b/arch/powerpc/platforms/pasemi/idle.c
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
+#include <linux/irq.h>
#include <asm/machdep.h>
#include <asm/reg.h>
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index c9894933084..93539676662 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -99,6 +99,7 @@ static void ps3_panic(char *str)
while(1);
}
+#ifdef CONFIG_FB_PS3
static void prealloc(struct ps3_prealloc *p)
{
if (!p->size)
@@ -115,7 +116,6 @@ static void prealloc(struct ps3_prealloc *p)
p->address);
}
-#ifdef CONFIG_FB_PS3
struct ps3_prealloc ps3fb_videomemory = {
.name = "ps3fb videomemory",
.size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 8729348c060..53416ec5198 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -118,9 +118,11 @@ static void __init ps3_smp_setup_cpu(int cpu)
DBG("%s:%d: (%d, %d) => virq %u\n",
__func__, __LINE__, cpu, i, virqs[i]);
+ result = request_irq(virqs[i], ipi_function_handler,
+ IRQF_DISABLED, names[i], (void*)(long)i);
- request_irq(virqs[i], ipi_function_handler, IRQF_DISABLED,
- names[i], (void*)(long)i);
+ if (result)
+ virqs[i] = NO_IRQ;
}
ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 3c48cce98a5..6bda51027cc 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -274,13 +274,13 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
- struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
- int i;
-
#if defined(CONFIG_PS3_DYNAMIC_DMA)
BUG_ON("do");
return -EPERM;
#else
+ struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+ int i;
+
for (i = 0; i < nents; i++, sg++) {
int result = ps3_dma_map(dev->d_region,
page_to_phys(sg->page) + sg->offset, sg->length,
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 9ce775c38ab..c3ce0bd12c0 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_FSL_PCIE) += fsl_pcie.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
+mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
+obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o
# contains only the suspend handler for time
obj-$(CONFIG_PM) += timer.o
diff --git a/arch/powerpc/sysdev/mv64x60.h b/arch/powerpc/sysdev/mv64x60.h
new file mode 100644
index 00000000000..2ff0b4ef268
--- /dev/null
+++ b/arch/powerpc/sysdev/mv64x60.h
@@ -0,0 +1,11 @@
+#ifndef __MV64X60_H__
+#define __MV64X60_H__
+
+#include <linux/init.h>
+
+extern void __init mv64x60_init_irq(void);
+extern unsigned int mv64x60_get_irq(void);
+
+extern void __init mv64x60_pci_init(void);
+
+#endif /* __MV64X60_H__ */
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
new file mode 100644
index 00000000000..4b0a9c88eeb
--- /dev/null
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -0,0 +1,422 @@
+/*
+ * Platform device setup for Marvell mv64360/mv64460 host bridges (Discovery)
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
+
+#include <asm/prom.h>
+
+/*
+ * These functions provide the necessary setup for the mv64x60 drivers.
+ * These drivers are unusual in that they work on both the MIPS and PowerPC
+ * architectures. Because of that, the drivers do not support the normal
+ * PowerPC of_platform_bus_type. They support platform_bus_type instead.
+ */
+
+/*
+ * Create MPSC platform devices
+ */
+static int __init mv64x60_mpsc_register_shared_pdev(struct device_node *np)
+{
+ struct platform_device *pdev;
+ struct resource r[2];
+ struct mpsc_shared_pdata pdata;
+ const phandle *ph;
+ struct device_node *mpscrouting, *mpscintr;
+ int err;
+
+ ph = of_get_property(np, "mpscrouting", NULL);
+ mpscrouting = of_find_node_by_phandle(*ph);
+ if (!mpscrouting)
+ return -ENODEV;
+
+ err = of_address_to_resource(mpscrouting, 0, &r[0]);
+ of_node_put(mpscrouting);
+ if (err)
+ return err;
+
+ ph = of_get_property(np, "mpscintr", NULL);
+ mpscintr = of_find_node_by_phandle(*ph);
+ if (!mpscintr)
+ return -ENODEV;
+
+ err = of_address_to_resource(mpscintr, 0, &r[1]);
+ of_node_put(mpscintr);
+ if (err)
+ return err;
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ pdev = platform_device_alloc(MPSC_SHARED_NAME, 0);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 2);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
+
+static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
+{
+ struct resource r[5];
+ struct mpsc_pdata pdata;
+ struct platform_device *pdev;
+ const unsigned int *prop;
+ const phandle *ph;
+ struct device_node *sdma, *brg;
+ int err;
+ int port_number;
+
+ /* only register the shared platform device the first time through */
+ if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
+ return err;
+
+ memset(r, 0, sizeof(r));
+
+ err = of_address_to_resource(np, 0, &r[0]);
+ if (err)
+ return err;
+
+ of_irq_to_resource(np, 0, &r[4]);
+
+ ph = of_get_property(np, "sdma", NULL);
+ sdma = of_find_node_by_phandle(*ph);
+ if (!sdma)
+ return -ENODEV;
+
+ of_irq_to_resource(sdma, 0, &r[3]);
+ err = of_address_to_resource(sdma, 0, &r[1]);
+ of_node_put(sdma);
+ if (err)
+ return err;
+
+ ph = of_get_property(np, "brg", NULL);
+ brg = of_find_node_by_phandle(*ph);
+ if (!brg)
+ return -ENODEV;
+
+ err = of_address_to_resource(brg, 0, &r[2]);
+ of_node_put(brg);
+ if (err)
+ return err;
+
+ prop = of_get_property(np, "block-index", NULL);
+ if (!prop)
+ return -ENODEV;
+ port_number = *(int *)prop;
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ pdata.cache_mgmt = 1; /* All current revs need this set */
+
+ prop = of_get_property(np, "max_idle", NULL);
+ if (prop)
+ pdata.max_idle = *prop;
+
+ prop = of_get_property(brg, "current-speed", NULL);
+ if (prop)
+ pdata.default_baud = *prop;
+
+ /* Default is 8 bits, no parity, no flow control */
+ pdata.default_bits = 8;
+ pdata.default_parity = 'n';
+ pdata.default_flow = 'n';
+
+ prop = of_get_property(np, "chr_1", NULL);
+ if (prop)
+ pdata.chr_1_val = *prop;
+
+ prop = of_get_property(np, "chr_2", NULL);
+ if (prop)
+ pdata.chr_2_val = *prop;
+
+ prop = of_get_property(np, "chr_10", NULL);
+ if (prop)
+ pdata.chr_10_val = *prop;
+
+ prop = of_get_property(np, "mpcr", NULL);
+ if (prop)
+ pdata.mpcr_val = *prop;
+
+ prop = of_get_property(brg, "bcr", NULL);
+ if (prop)
+ pdata.bcr_val = *prop;
+
+ pdata.brg_can_tune = 1; /* All current revs need this set */
+
+ prop = of_get_property(brg, "clock-src", NULL);
+ if (prop)
+ pdata.brg_clk_src = *prop;
+
+ prop = of_get_property(brg, "clock-frequency", NULL);
+ if (prop)
+ pdata.brg_clk_freq = *prop;
+
+ pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 5);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
+/*
+ * Create mv64x60_eth platform devices
+ */
+static int __init eth_register_shared_pdev(struct device_node *np)
+{
+ struct platform_device *pdev;
+ struct resource r[1];
+ int err;
+
+ np = of_get_parent(np);
+ if (!np)
+ return -ENODEV;
+
+ err = of_address_to_resource(np, 0, &r[0]);
+ of_node_put(np);
+ if (err)
+ return err;
+
+ pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, 0,
+ r, 1);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+static int __init mv64x60_eth_device_setup(struct device_node *np, int id)
+{
+ struct resource r[1];
+ struct mv643xx_eth_platform_data pdata;
+ struct platform_device *pdev;
+ struct device_node *phy;
+ const u8 *mac_addr;
+ const int *prop;
+ const phandle *ph;
+ int err;
+
+ /* only register the shared platform device the first time through */
+ if (id == 0 && (err = eth_register_shared_pdev(np)))
+ return err;;
+
+ memset(r, 0, sizeof(r));
+ of_irq_to_resource(np, 0, &r[0]);
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ prop = of_get_property(np, "block-index", NULL);
+ if (!prop)
+ return -ENODEV;
+ pdata.port_number = *prop;
+
+ mac_addr = of_get_mac_address(np);
+ if (mac_addr)
+ memcpy(pdata.mac_addr, mac_addr, 6);
+
+ prop = of_get_property(np, "speed", NULL);
+ if (prop)
+ pdata.speed = *prop;
+
+ prop = of_get_property(np, "tx_queue_size", NULL);
+ if (prop)
+ pdata.tx_queue_size = *prop;
+
+ prop = of_get_property(np, "rx_queue_size", NULL);
+ if (prop)
+ pdata.rx_queue_size = *prop;
+
+ prop = of_get_property(np, "tx_sram_addr", NULL);
+ if (prop)
+ pdata.tx_sram_addr = *prop;
+
+ prop = of_get_property(np, "tx_sram_size", NULL);
+ if (prop)
+ pdata.tx_sram_size = *prop;
+
+ prop = of_get_property(np, "rx_sram_addr", NULL);
+ if (prop)
+ pdata.rx_sram_addr = *prop;
+
+ prop = of_get_property(np, "rx_sram_size", NULL);
+ if (prop)
+ pdata.rx_sram_size = *prop;
+
+ ph = of_get_property(np, "phy", NULL);
+ if (!ph)
+ return -ENODEV;
+
+ phy = of_find_node_by_phandle(*ph);
+ if (phy == NULL)
+ return -ENODEV;
+
+ prop = of_get_property(phy, "reg", NULL);
+ if (prop) {
+ pdata.force_phy_addr = 1;
+ pdata.phy_addr = *prop;
+ }
+
+ of_node_put(phy);
+
+ pdev = platform_device_alloc(MV643XX_ETH_NAME, pdata.port_number);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 1);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
+/*
+ * Create mv64x60_i2c platform devices
+ */
+static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
+{
+ struct resource r[2];
+ struct platform_device *pdev;
+ struct mv64xxx_i2c_pdata pdata;
+ const unsigned int *prop;
+ int err;
+
+ memset(r, 0, sizeof(r));
+
+ err = of_address_to_resource(np, 0, &r[0]);
+ if (err)
+ return err;
+
+ of_irq_to_resource(np, 0, &r[1]);
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ prop = of_get_property(np, "freq_m", NULL);
+ if (!prop)
+ return -ENODEV;
+ pdata.freq_m = *prop;
+
+ prop = of_get_property(np, "freq_n", NULL);
+ if (!prop)
+ return -ENODEV;
+ pdata.freq_n = *prop;
+
+ prop = of_get_property(np, "timeout", NULL);
+ if (prop)
+ pdata.timeout = *prop;
+ else
+ pdata.timeout = 1000; /* 1 second */
+
+ prop = of_get_property(np, "retries", NULL);
+ if (prop)
+ pdata.retries = *prop;
+ else
+ pdata.retries = 1;
+
+ pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 2);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
+static int __init mv64x60_device_setup(void)
+{
+ struct device_node *np = NULL;
+ int id;
+ int err;
+
+ for (id = 0;
+ (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); id++)
+ if ((err = mv64x60_mpsc_device_setup(np, id)))
+ goto error;
+
+ for (id = 0;
+ (np = of_find_compatible_node(np, "network",
+ "marvell,mv64x60-eth"));
+ id++)
+ if ((err = mv64x60_eth_device_setup(np, id)))
+ goto error;
+
+ for (id = 0;
+ (np = of_find_compatible_node(np, "i2c", "marvell,mv64x60-i2c"));
+ id++)
+ if ((err = mv64x60_i2c_device_setup(np, id)))
+ goto error;
+
+ return 0;
+
+error:
+ of_node_put(np);
+ return err;
+}
+arch_initcall(mv64x60_device_setup);
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
new file mode 100644
index 00000000000..b5aef4cbc8d
--- /dev/null
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -0,0 +1,172 @@
+/*
+ * PCI bus setup for Marvell mv64360/mv64460 host bridges (Discovery)
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+#define PCI_HEADER_TYPE_INVALID 0x7f /* Invalid PCI header type */
+
+#ifdef CONFIG_SYSFS
+/* 32-bit hex or dec stringified number + '\n' */
+#define MV64X60_VAL_LEN_MAX 11
+#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
+
+static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct pci_dev *phb;
+ u32 v;
+
+ if (off > 0)
+ return 0;
+ if (count < MV64X60_VAL_LEN_MAX)
+ return -EINVAL;
+
+ phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ if (!phb)
+ return -ENODEV;
+ pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
+ pci_dev_put(phb);
+
+ return sprintf(buf, "0x%08x\n", v);
+}
+
+static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct pci_dev *phb;
+ u32 v;
+
+ if (off > 0)
+ return 0;
+ if (count <= 0)
+ return -EINVAL;
+
+ if (sscanf(buf, "%i", &v) != 1)
+ return -EINVAL;
+
+ phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ if (!phb)
+ return -ENODEV;
+ pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
+ pci_dev_put(phb);
+
+ return count;
+}
+
+static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
+ .attr = {
+ .name = "hs_reg",
+ .mode = S_IRUGO | S_IWUSR,
+ .owner = THIS_MODULE,
+ },
+ .size = MV64X60_VAL_LEN_MAX,
+ .read = mv64x60_hs_reg_read,
+ .write = mv64x60_hs_reg_write,
+};
+
+static int __init mv64x60_sysfs_init(void)
+{
+ struct device_node *np;
+ struct platform_device *pdev;
+ const unsigned int *prop;
+
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60");
+ if (!np)
+ return 0;
+
+ prop = of_get_property(np, "hs_reg_valid", NULL);
+ of_node_put(np);
+
+ pdev = platform_device_register_simple("marvell,mv64x60", 0, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return sysfs_create_bin_file(&pdev->dev.kobj, &mv64x60_hs_reg_attr);
+}
+
+subsys_initcall(mv64x60_sysfs_init);
+
+#endif /* CONFIG_SYSFS */
+
+static void __init mv64x60_pci_fixup_early(struct pci_dev *dev)
+{
+ /*
+ * Set the host bridge hdr_type to an invalid value so that
+ * pci_setup_device() will ignore the host bridge.
+ */
+ dev->hdr_type = PCI_HEADER_TYPE_INVALID;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360,
+ mv64x60_pci_fixup_early);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64460,
+ mv64x60_pci_fixup_early);
+
+static int __init mv64x60_add_bridge(struct device_node *dev)
+{
+ int len;
+ struct pci_controller *hose;
+ struct resource rsrc;
+ const int *bus_range;
+ int primary;
+
+ memset(&rsrc, 0, sizeof(rsrc));
+
+ /* Fetch host bridge registers address */
+ if (of_address_to_resource(dev, 0, &rsrc)) {
+ printk(KERN_ERR "No PCI reg property in device tree\n");
+ return -ENODEV;
+ }
+
+ /* Get bus range if any */
+ bus_range = of_get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int))
+ printk(KERN_WARNING "Can't get bus-range for %s, assume"
+ " bus 0\n", dev->full_name);
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return -ENOMEM;
+
+ hose->arch_data = dev;
+ hose->set_cfg_type = 1;
+
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ setup_indirect_pci(hose, rsrc.start, rsrc.start + 4);
+ hose->bus_offset = hose->first_busno;
+
+ printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. "
+ "Firmware bus number: %d->%d\n",
+ (unsigned long long)rsrc.start, hose->first_busno,
+ hose->last_busno);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ primary = (hose->first_busno == 0);
+ pci_process_bridge_OF_ranges(hose, dev, primary);
+
+ return 0;
+}
+
+void __init mv64x60_pci_init(void)
+{
+ struct device_node *np = NULL;
+
+ while ((np = of_find_compatible_node(np, "pci", "marvell,mv64x60-pci")))
+ mv64x60_add_bridge(np);
+}
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
new file mode 100644
index 00000000000..01d31628777
--- /dev/null
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -0,0 +1,305 @@
+/*
+ * Interrupt handling for Marvell mv64360/mv64460 host bridges (Discovery)
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/irq.h>
+
+#include "mv64x60.h"
+
+/* Interrupt Controller Interface Registers */
+#define MV64X60_IC_MAIN_CAUSE_LO 0x0004
+#define MV64X60_IC_MAIN_CAUSE_HI 0x000c
+#define MV64X60_IC_CPU0_INTR_MASK_LO 0x0014
+#define MV64X60_IC_CPU0_INTR_MASK_HI 0x001c
+#define MV64X60_IC_CPU0_SELECT_CAUSE 0x0024
+
+#define MV64X60_HIGH_GPP_GROUPS 0x0f000000
+#define MV64X60_SELECT_CAUSE_HIGH 0x40000000
+
+/* General Purpose Pins Controller Interface Registers */
+#define MV64x60_GPP_INTR_CAUSE 0x0008
+#define MV64x60_GPP_INTR_MASK 0x000c
+
+#define MV64x60_LEVEL1_LOW 0
+#define MV64x60_LEVEL1_HIGH 1
+#define MV64x60_LEVEL1_GPP 2
+
+#define MV64x60_LEVEL1_MASK 0x00000060
+#define MV64x60_LEVEL1_OFFSET 5
+
+#define MV64x60_LEVEL2_MASK 0x0000001f
+
+#define MV64x60_NUM_IRQS 96
+
+static DEFINE_SPINLOCK(mv64x60_lock);
+
+static void __iomem *mv64x60_irq_reg_base;
+static void __iomem *mv64x60_gpp_reg_base;
+
+/*
+ * Interrupt Controller Handling
+ *
+ * The interrupt controller handles three groups of interrupts:
+ * main low: IRQ0-IRQ31
+ * main high: IRQ32-IRQ63
+ * gpp: IRQ64-IRQ95
+ *
+ * This code handles interrupts in two levels. Level 1 selects the
+ * interrupt group, and level 2 selects an IRQ within that group.
+ * Each group has its own irq_chip structure.
+ */
+
+static u32 mv64x60_cached_low_mask;
+static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
+static u32 mv64x60_cached_gpp_mask;
+
+static struct irq_host *mv64x60_irq_host;
+
+/*
+ * mv64x60_chip_low functions
+ */
+
+static void mv64x60_mask_low(unsigned int virq)
+{
+ int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ mv64x60_cached_low_mask &= ~(1 << level2);
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
+ mv64x60_cached_low_mask);
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+ (void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
+}
+
+static void mv64x60_unmask_low(unsigned int virq)
+{
+ int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ mv64x60_cached_low_mask |= 1 << level2;
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
+ mv64x60_cached_low_mask);
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+ (void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
+}
+
+static struct irq_chip mv64x60_chip_low = {
+ .name = "mv64x60_low",
+ .mask = mv64x60_mask_low,
+ .mask_ack = mv64x60_mask_low,
+ .unmask = mv64x60_unmask_low,
+};
+
+/*
+ * mv64x60_chip_high functions
+ */
+
+static void mv64x60_mask_high(unsigned int virq)
+{
+ int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ mv64x60_cached_high_mask &= ~(1 << level2);
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
+ mv64x60_cached_high_mask);
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+ (void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
+}
+
+static void mv64x60_unmask_high(unsigned int virq)
+{
+ int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ mv64x60_cached_high_mask |= 1 << level2;
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
+ mv64x60_cached_high_mask);
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+ (void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
+}
+
+static struct irq_chip mv64x60_chip_high = {
+ .name = "mv64x60_high",
+ .mask = mv64x60_mask_high,
+ .mask_ack = mv64x60_mask_high,
+ .unmask = mv64x60_unmask_high,
+};
+
+/*
+ * mv64x60_chip_gpp functions
+ */
+
+static void mv64x60_mask_gpp(unsigned int virq)
+{
+ int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ mv64x60_cached_gpp_mask &= ~(1 << level2);
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+ mv64x60_cached_gpp_mask);
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+ (void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
+}
+
+static void mv64x60_mask_ack_gpp(unsigned int virq)
+{
+ int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ mv64x60_cached_gpp_mask &= ~(1 << level2);
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+ mv64x60_cached_gpp_mask);
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE,
+ ~(1 << level2));
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+ (void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
+}
+
+static void mv64x60_unmask_gpp(unsigned int virq)
+{
+ int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ mv64x60_cached_gpp_mask |= 1 << level2;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+ mv64x60_cached_gpp_mask);
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+ (void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
+}
+
+static struct irq_chip mv64x60_chip_gpp = {
+ .name = "mv64x60_gpp",
+ .mask = mv64x60_mask_gpp,
+ .mask_ack = mv64x60_mask_ack_gpp,
+ .unmask = mv64x60_unmask_gpp,
+};
+
+/*
+ * mv64x60_host_ops functions
+ */
+
+static int mv64x60_host_match(struct irq_host *h, struct device_node *np)
+{
+ return mv64x60_irq_host->host_data == np;
+}
+
+static struct irq_chip *mv64x60_chips[] = {
+ [MV64x60_LEVEL1_LOW] = &mv64x60_chip_low,
+ [MV64x60_LEVEL1_HIGH] = &mv64x60_chip_high,
+ [MV64x60_LEVEL1_GPP] = &mv64x60_chip_gpp,
+};
+
+static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ int level1;
+
+ get_irq_desc(virq)->status |= IRQ_LEVEL;
+
+ level1 = (hwirq & MV64x60_LEVEL1_MASK) >> MV64x60_LEVEL1_OFFSET;
+ BUG_ON(level1 > MV64x60_LEVEL1_GPP);
+ set_irq_chip_and_handler(virq, mv64x60_chips[level1], handle_level_irq);
+
+ return 0;
+}
+
+static struct irq_host_ops mv64x60_host_ops = {
+ .match = mv64x60_host_match,
+ .map = mv64x60_host_map,
+};
+
+/*
+ * Global functions
+ */
+
+void __init mv64x60_init_irq(void)
+{
+ struct device_node *np;
+ phys_addr_t paddr;
+ unsigned int size;
+ const unsigned int *reg;
+ unsigned long flags;
+
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-gpp");
+ reg = of_get_property(np, "reg", &size);
+ paddr = of_translate_address(np, reg);
+ mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
+ of_node_put(np);
+
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-pic");
+ reg = of_get_property(np, "reg", &size);
+ paddr = of_translate_address(np, reg);
+ of_node_put(np);
+ mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
+
+ mv64x60_irq_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, MV64x60_NUM_IRQS,
+ &mv64x60_host_ops, MV64x60_NUM_IRQS);
+
+ mv64x60_irq_host->host_data = np;
+
+ spin_lock_irqsave(&mv64x60_lock, flags);
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+ mv64x60_cached_gpp_mask);
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
+ mv64x60_cached_low_mask);
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
+ mv64x60_cached_high_mask);
+
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE, 0);
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_LO, 0);
+ out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_HI, 0);
+ spin_unlock_irqrestore(&mv64x60_lock, flags);
+}
+
+unsigned int mv64x60_get_irq(void)
+{
+ u32 cause;
+ int level1;
+ irq_hw_number_t hwirq;
+ int virq = NO_IRQ;
+
+ cause = in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_SELECT_CAUSE);
+ if (cause & MV64X60_SELECT_CAUSE_HIGH) {
+ cause &= mv64x60_cached_high_mask;
+ level1 = MV64x60_LEVEL1_HIGH;
+ if (cause & MV64X60_HIGH_GPP_GROUPS) {
+ cause = in_le32(mv64x60_gpp_reg_base +
+ MV64x60_GPP_INTR_CAUSE);
+ cause &= mv64x60_cached_gpp_mask;
+ level1 = MV64x60_LEVEL1_GPP;
+ }
+ } else {
+ cause &= mv64x60_cached_low_mask;
+ level1 = MV64x60_LEVEL1_LOW;
+ }
+ if (cause) {
+ hwirq = (level1 << MV64x60_LEVEL1_OFFSET) | __ilog2(cause);
+ virq = irq_linear_revmap(mv64x60_irq_host, hwirq);
+ }
+
+ return virq;
+}
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
index e35483961b9..efa0a56e230 100644
--- a/arch/ppc/4xx_io/serial_sicc.c
+++ b/arch/ppc/4xx_io/serial_sicc.c
@@ -3,7 +3,7 @@
*
* Based on drivers/char/serial_amba.c, by ARM Ltd.
*
- * Copyright 2001 IBM Crop.
+ * Copyright 2001 IBM Corp.
* Author: IBM China Research Lab
* Yudong Yang <yangyud@cn.ibm.com>
* Yi Ge <geyi@cn.ibm.com>
@@ -155,16 +155,16 @@
/* serial port transmit command register */
-#define _TxCR_ET_MASK 0x80 /* transmiter enable mask */
+#define _TxCR_ET_MASK 0x80 /* transmitter enable mask */
#define _TxCR_DME_MASK 0x60 /* dma mode mask */
#define _TxCR_TIE_MASK 0x10 /* empty interrupt enable mask */
#define _TxCR_EIE_MASK 0x08 /* error interrupt enable mask */
#define _TxCR_SPE_MASK 0x04 /* stop/pause mask */
#define _TxCR_TB_MASK 0x02 /* transmit break mask */
-#define _TxCR_ET_ENABLE _TxCR_ET_MASK /* transmiter enabled */
-#define _TxCR_DME_DISABLE 0x00 /* transmiter disabled, TBR intr disabled */
-#define _TxCR_DME_TBR 0x20 /* transmiter disabled, TBR intr enabled */
+#define _TxCR_ET_ENABLE _TxCR_ET_MASK /* transmitter enabled */
+#define _TxCR_DME_DISABLE 0x00 /* transmitter disabled, TBR intr disabled */
+#define _TxCR_DME_TBR 0x20 /* transmitter disabled, TBR intr enabled */
#define _TxCR_DME_CHAN_2 0x40 /* dma enabled, destination chann 2 */
#define _TxCR_DME_CHAN_3 0x60 /* dma enabled, destination chann 3 */
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index e2c6210f234..7088428e1fe 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -144,7 +144,7 @@ m8xx_cpm_reset(void)
/* Set SDMA Bus Request priority 5.
* On 860T, this also enables FEC priority 6. I am not sure
- * this is what we realy want for some applications, but the
+ * this is what we really want for some applications, but the
* manual recommends it.
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
*/
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
index 57a9a61e54b..d38335d2d71 100644
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -1878,7 +1878,7 @@ fec_restart(struct net_device *dev, int duplex)
bdp--;
bdp->cbd_sc |= BD_SC_WRAP;
- /* ...and the same for transmmit.
+ /* ...and the same for transmit.
*/
bdp = fep->tx_bd_base;
for (i=0; i<TX_RING_SIZE; i++) {
diff --git a/arch/ppc/boot/lib/vreset.c b/arch/ppc/boot/lib/vreset.c
index 463ba001fb9..98539e9f7f9 100644
--- a/arch/ppc/boot/lib/vreset.c
+++ b/arch/ppc/boot/lib/vreset.c
@@ -518,7 +518,7 @@ setTextRegs(struct VgaRegs *svp)
outb(0x3c6, 0xff); /* MASK */
for ( i = 0; i < 0x10; i++)
- writeAttr(i, AC[i], 0); /* pallete */
+ writeAttr(i, AC[i], 0); /* palette */
writeAttr(0x10, 0x0c, 0); /* text mode */
writeAttr(0x11, 0x00, 0); /* overscan color (border) */
writeAttr(0x12, 0x0f, 0); /* plane enable */
diff --git a/arch/ppc/boot/simple/m8xx_tty.c b/arch/ppc/boot/simple/m8xx_tty.c
index cacc40fdbcf..ea615d8ca54 100644
--- a/arch/ppc/boot/simple/m8xx_tty.c
+++ b/arch/ppc/boot/simple/m8xx_tty.c
@@ -1,7 +1,7 @@
/* Minimal serial functions needed to send messages out the serial
* port on the MBX console.
*
- * The MBX uxes SMC1 for the serial port. We reset the port and use
+ * The MBX uses SMC1 for the serial port. We reset the port and use
* only the first BD that EPPC-Bug set up as a character FIFO.
*
* Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
diff --git a/arch/ppc/boot/simple/misc-embedded.c b/arch/ppc/boot/simple/misc-embedded.c
index 10219eeca05..8a08ad397ed 100644
--- a/arch/ppc/boot/simple/misc-embedded.c
+++ b/arch/ppc/boot/simple/misc-embedded.c
@@ -136,7 +136,7 @@ load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *b
/*
* We link ourself to an arbitrary low address. When we run, we
- * relocate outself to that address. __image_being points to
+ * relocate ourself to that address. __image_being points to
* the part of the image where the zImage is. -- Tom
*/
zimage_start = (char *)(unsigned long)(&__image_begin);
diff --git a/arch/ppc/boot/simple/mpc52xx_tty.c b/arch/ppc/boot/simple/mpc52xx_tty.c
index 7b5924cc3c0..6955891fb03 100644
--- a/arch/ppc/boot/simple/mpc52xx_tty.c
+++ b/arch/ppc/boot/simple/mpc52xx_tty.c
@@ -33,7 +33,7 @@ static struct mpc52xx_psc __iomem *psc =
* rtc. We read the decrementer change during one rtc tick
* and multiply by 4 to get the system bus clock frequency. Since a
* rtc tick is one seconds, and that's pretty long, we change the rtc
- * dividers temporarly to set them 64x faster ;)
+ * dividers temporarily to set them 64x faster ;)
*/
static int
mpc52xx_ipbfreq(void)
diff --git a/arch/ppc/boot/simple/mv64x60_tty.c b/arch/ppc/boot/simple/mv64x60_tty.c
index 781e040a97d..8a735787a6e 100644
--- a/arch/ppc/boot/simple/mv64x60_tty.c
+++ b/arch/ppc/boot/simple/mv64x60_tty.c
@@ -338,7 +338,7 @@ serial_tstc(unsigned long com_port)
rdp = &rd[com_port][cur_rd[com_port]];
- /* Go thru rcv desc's until empty looking for one with data (no error)*/
+ /* Go through rcv descs until empty looking for one with data (no error)*/
while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) &&
(loop_count++ < RX_NUM_DESC)) {
diff --git a/arch/ppc/boot/simple/rw4/stb.h b/arch/ppc/boot/simple/rw4/stb.h
index fd98ee0f843..9afa5ab24d2 100644
--- a/arch/ppc/boot/simple/rw4/stb.h
+++ b/arch/ppc/boot/simple/rw4/stb.h
@@ -88,7 +88,7 @@
/*----------------------------------------------------------------------------+
| STB tasks, task stack sizes, and task priorities. The actual task priority
| is 1 more than the specified number since priority 0 is reserved (system
-| internaly adds 1 to supplied priority number).
+| internally adds 1 to supplied priority number).
+----------------------------------------------------------------------------*/
#define STB_IDLE_TASK_SS (5* 1024)
#define STB_IDLE_TASK_PRIO 0
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 810f7aa72e9..aea100be52c 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -577,7 +577,7 @@ void program_check_exception(struct pt_regs *regs)
* ESR_DST (!?) or 0. In the process of chasing this with the
* hardware people - not sure if it can happen on any illegal
* instruction or only on FP instructions, whether there is a
- * pattern to occurences etc. -dgibson 31/Mar/2003 */
+ * pattern to occurrences etc. -dgibson 31/Mar/2003 */
if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
emulate_single_step(regs);
return;
@@ -860,7 +860,7 @@ void SPEFloatingPointException(struct pt_regs *regs)
spefscr = current->thread.spefscr;
fpexc_mode = current->thread.fpexc_mode;
- /* Hardware does not neccessarily set sticky
+ /* Hardware does not necessarily set sticky
* underflow/overflow/invalid flags */
if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) {
code = FPE_FLTOVF;
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index c374e53ae03..390dd1995c2 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -48,7 +48,7 @@
#include "mmu_decl.h"
#if defined(CONFIG_KERNEL_START_BOOL) || defined(CONFIG_LOWMEM_SIZE_BOOL)
-/* The ammount of lowmem must be within 0xF0000000 - KERNELBASE. */
+/* The amount of lowmem must be within 0xF0000000 - KERNELBASE. */
#if (CONFIG_LOWMEM_SIZE > (0xF0000000 - KERNELBASE))
#error "You must adjust CONFIG_LOWMEM_SIZE or CONFIG_START_KERNEL"
#endif
diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c
index 75857b38e89..1a7f075b754 100644
--- a/arch/ppc/platforms/4xx/bubinga.c
+++ b/arch/ppc/platforms/4xx/bubinga.c
@@ -197,7 +197,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
- /* end work arround */
+ /* end workaround */
#ifdef DEBUG
printk("PCI bridge regs after fixup \n");
diff --git a/arch/ppc/platforms/4xx/ep405.c b/arch/ppc/platforms/4xx/ep405.c
index e5adf9ba1fc..5aa29502280 100644
--- a/arch/ppc/platforms/4xx/ep405.c
+++ b/arch/ppc/platforms/4xx/ep405.c
@@ -130,7 +130,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
- /* end work arround */
+ /* end workaround */
#endif
}
diff --git a/arch/ppc/platforms/4xx/ibmnp405h.h b/arch/ppc/platforms/4xx/ibmnp405h.h
index 4aa8821b478..08a6a779190 100644
--- a/arch/ppc/platforms/4xx/ibmnp405h.h
+++ b/arch/ppc/platforms/4xx/ibmnp405h.h
@@ -80,7 +80,7 @@
#define DCRN_CPMFR_BASE 0x0B9
#define DCRN_CPMER_BASE 0x0B8
-/* CPM Clocking & Power Mangement defines */
+/* CPM Clocking & Power Management defines */
#define IBM_CPM_PCI 0x40000000 /* PCI */
#define IBM_CPM_EMAC2 0x20000000 /* EMAC 2 MII */
#define IBM_CPM_EMAC3 0x04000000 /* EMAC 3 MII */
diff --git a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
index c47493e344c..8689f3e8ef3 100644
--- a/arch/ppc/platforms/4xx/sycamore.c
+++ b/arch/ppc/platforms/4xx/sycamore.c
@@ -225,7 +225,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
- /* end work arround */
+ /* end workaround */
#ifdef DEBUG
printk("PCI bridge regs after fixup \n");
diff --git a/arch/ppc/platforms/4xx/walnut.c b/arch/ppc/platforms/4xx/walnut.c
index f414d2d4c58..2f977234085 100644
--- a/arch/ppc/platforms/4xx/walnut.c
+++ b/arch/ppc/platforms/4xx/walnut.c
@@ -200,7 +200,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
hose->first_busno, PCI_SLOT(hose->first_busno),
PCI_FUNC(hose->first_busno), bar, bar_response);
}
- /* end work arround */
+ /* end work around */
#ifdef DEBUG
printk("PCI bridge regs after fixup \n");
diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
index f87e06f6bab..f8baf05f16c 100644
--- a/arch/ppc/platforms/ev64360.c
+++ b/arch/ppc/platforms/ev64360.c
@@ -473,7 +473,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
* are non-zero, then we should use the board info from the bd_t
* structure and the cmdline pointed to by r6 instead of the
* information from birecs, if any. Otherwise, use the information
- * from birecs as discovered by the preceeding call to
+ * from birecs as discovered by the preceding call to
* parse_bootinfo(). This rule should work with both PPCBoot, which
* uses a bd_t board info structure, and the kernel boot wrapper,
* which uses birecs.
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index d809e17aa53..ca5de13712f 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -144,7 +144,7 @@ static void __init hdpu_setup_peripherals(void)
/* Enable pipelining */
mv64x60_set_bits(&bh, MV64x60_CPU_CONFIG, (1 << 13));
- /* Enable Snoop Pipelineing */
+ /* Enable Snoop Pipelining */
mv64x60_set_bits(&bh, MV64360_D_UNIT_CONTROL_HIGH, (1 << 24));
/*
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
index 720f8b3e2fb..c289e9f1b25 100644
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -880,7 +880,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
* are non-zero, then we should use the board info from the bd_t
* structure and the cmdline pointed to by r6 instead of the
* information from birecs, if any. Otherwise, use the information
- * from birecs as discovered by the preceeding call to
+ * from birecs as discovered by the preceding call to
* parse_bootinfo(). This rule should work with both PPCBoot, which
* uses a bd_t board info structure, and the kernel boot wrapper,
* which uses birecs.
diff --git a/arch/ppc/platforms/mbx.h b/arch/ppc/platforms/mbx.h
index fe81ca4ea0a..1cf36fa3592 100644
--- a/arch/ppc/platforms/mbx.h
+++ b/arch/ppc/platforms/mbx.h
@@ -37,7 +37,7 @@ typedef struct bd_info {
/* Memory map for the MBX as configured by EPPC-Bug. We could reprogram
* The SIU and PCI bridge, and try to use larger MMU pages, but the
- * performance gain is not measureable and it certainly complicates the
+ * performance gain is not measurable and it certainly complicates the
* generic MMU model.
*
* In a effort to minimize memory usage for embedded applications, any
diff --git a/arch/ppc/platforms/mvme5100.h b/arch/ppc/platforms/mvme5100.h
index 9e2a09e636a..fbb5495165c 100644
--- a/arch/ppc/platforms/mvme5100.h
+++ b/arch/ppc/platforms/mvme5100.h
@@ -69,7 +69,7 @@
#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
-/* All UART IRQ's are wire-OR'd to one MPIC IRQ */
+/* All UART IRQs are wire-OR'd to one MPIC IRQ */
#define STD_SERIAL_PORT_DFNS \
{ 0, BASE_BAUD, MVME5100_SERIAL_1, \
MVME5100_SERIAL_IRQ, \
diff --git a/arch/ppc/platforms/pplus.h b/arch/ppc/platforms/pplus.h
index a07cbbdd72c..a4bbaa8d858 100644
--- a/arch/ppc/platforms/pplus.h
+++ b/arch/ppc/platforms/pplus.h
@@ -18,7 +18,7 @@
#include <asm/io.h>
/*
- * Due to limiations imposed by legacy hardware (primaryily IDE controllers),
+ * Due to limitations imposed by legacy hardware (primarily IDE controllers),
* the PPLUS boards operate using a PReP address map.
*
* From Processor (physical) -> PCI:
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
index c627ba41335..1df3150f016 100644
--- a/arch/ppc/platforms/prep_pci.c
+++ b/arch/ppc/platforms/prep_pci.c
@@ -589,9 +589,9 @@ static unsigned char prep_pci_intpins[4][4] =
{ 4, 1, 2, 3}, /* Buses 3, 7, 11 ... */
};
-/* We have to turn on LEVEL mode for changed IRQ's */
-/* All PCI IRQ's need to be level mode, so this should be something
- * other than hard-coded as well... IRQ's are individually mappable
+/* We have to turn on LEVEL mode for changed IRQs */
+/* All PCI IRQs need to be level mode, so this should be something
+ * other than hard-coded as well... IRQs are individually mappable
* to either edge or level.
*/
@@ -923,8 +923,8 @@ prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
Motherboard_map_name = "IBM 6015/7020 (Sandalfoot/Sandalbow)";
Motherboard_map = ibm6015_pci_IRQ_map;
Motherboard_routes = ibm6015_pci_IRQ_routes;
- *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
- *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
+ *irq_edge_mask_lo = 0x00; /* IRQs 0-7 all edge-triggered */
+ *irq_edge_mask_hi = 0xA0; /* IRQs 13, 15 level-triggered */
}
void __init
@@ -933,8 +933,8 @@ prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
Motherboard_map_name = "IBM Thinkpad 850/860";
Motherboard_map = Nobis_pci_IRQ_map;
Motherboard_routes = Nobis_pci_IRQ_routes;
- *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
- *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
+ *irq_edge_mask_lo = 0x00; /* IRQs 0-7 all edge-triggered */
+ *irq_edge_mask_hi = 0xA0; /* IRQs 13, 15 level-triggered */
}
void __init
@@ -943,8 +943,8 @@ prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
Motherboard_map_name = "IBM 7248, PowerSeries 830/850 (Carolina)";
Motherboard_map = ibm8xx_pci_IRQ_map;
Motherboard_routes = ibm8xx_pci_IRQ_routes;
- *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
- *irq_edge_mask_hi = 0xA4; /* irq's 10, 13, 15 level-triggered */
+ *irq_edge_mask_lo = 0x00; /* IRQs 0-7 all edge-triggered */
+ *irq_edge_mask_hi = 0xA4; /* IRQs 10, 13, 15 level-triggered */
}
void __init
@@ -954,8 +954,8 @@ prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
Motherboard_map = ibm43p_pci_IRQ_map;
Motherboard_routes = ibm43p_pci_IRQ_routes;
Motherboard_non0 = ibm43p_pci_map_non0;
- *irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
- *irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
+ *irq_edge_mask_lo = 0x00; /* IRQs 0-7 all edge-triggered */
+ *irq_edge_mask_hi = 0xA0; /* IRQs 13, 15 level-triggered */
}
void __init
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index f166299571d..6f21110a974 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -593,7 +593,7 @@ static void __init prep_init_sound(void)
PPC_DEVICE *audiodevice = NULL;
/*
- * Get the needed resource informations from residual data.
+ * Get the needed resource information from residual data.
*
*/
if (have_residual_data)
@@ -632,9 +632,9 @@ static void __init prep_init_sound(void)
}
/*
- * Find a way to push these informations to the cs4232 driver
+ * Find a way to push this information to the cs4232 driver
* Give it out with printk, when not in cmd_line?
- * Append it to cmd_line and boot_command_line?
+ * Append it to cmd_line and boot_command_line?
* Format is cs4232=io,irq,dma,dma2
*/
}
diff --git a/arch/ppc/platforms/prpmc750.h b/arch/ppc/platforms/prpmc750.h
index 4c7adcc9ae3..c4dcff09d7c 100644
--- a/arch/ppc/platforms/prpmc750.h
+++ b/arch/ppc/platforms/prpmc750.h
@@ -16,7 +16,7 @@
#define __ASM_PRPMC750_H__
/*
- * Due to limiations imposed by legacy hardware (primaryily IDE controllers),
+ * Due to limitations imposed by legacy hardware (primarily IDE controllers),
* the PrPMC750 carrier board operates using a PReP address map.
*
* From Processor (physical) -> PCI:
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 13d70ab50bf..b55860734a7 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -1371,7 +1371,7 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
* are non-zero, then we should use the board info from the bd_t
* structure and the cmdline pointed to by r6 instead of the
* information from birecs, if any. Otherwise, use the information
- * from birecs as discovered by the preceeding call to
+ * from birecs as discovered by the preceding call to
* parse_bootinfo(). This rule should work with both PPCBoot, which
* uses a bd_t board info structure, and the kernel boot wrapper,
* which uses birecs.
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
index a76002af686..3352fae1c72 100644
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -54,7 +54,7 @@
*
*
* Motorola has finally released a version of DINK32 that correctly
- * (seemingly) initalizes the memory controller correctly, regardless
+ * (seemingly) initializes the memory controller correctly, regardless
* of the amount of memory in the system. Once a method of determining
* what version of DINK initializes the system for us, if applicable, is
* found, we can hopefully stop hardcoding 32MB of RAM.
@@ -473,7 +473,7 @@ sandpoint_request_io(void)
arch_initcall(sandpoint_request_io);
/*
- * Interrupt setup and service. Interrrupts on the Sandpoint come
+ * Interrupt setup and service. Interrupts on the Sandpoint come
* from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO).
* The 8259 is cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4,
* IDE is on EPIC 7 and 8.
@@ -505,7 +505,7 @@ sandpoint_find_end_of_memory(void)
if (bp->bi_memsize)
return bp->bi_memsize;
- /* DINK32 13.0 correctly initalizes things, so iff you use
+ /* DINK32 13.0 correctly initializes things, so iff you use
* this you _should_ be able to change this instead of a
* hardcoded value. */
#if 0
@@ -677,7 +677,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
* are non-zero, then we should use the board info from the bd_t
* structure and the cmdline pointed to by r6 instead of the
* information from birecs, if any. Otherwise, use the information
- * from birecs as discovered by the preceeding call to
+ * from birecs as discovered by the preceding call to
* parse_bootinfo(). This rule should work with both PPCBoot, which
* uses a bd_t board info structure, and the kernel boot wrapper,
* which uses birecs.
diff --git a/arch/ppc/syslib/harrier.c b/arch/ppc/syslib/harrier.c
index c1583f48832..45b797b3a33 100644
--- a/arch/ppc/syslib/harrier.c
+++ b/arch/ppc/syslib/harrier.c
@@ -210,7 +210,7 @@ harrier_init(struct pci_controller *hose,
* This assumes that PPCBug has initialized the memory controller (SMC)
* on the Harrier correctly (i.e., it does no sanity checking).
* It also assumes that the memory base registers are set to configure the
- * memory as contigous starting with "RAM A BASE", "RAM B BASE", etc.
+ * memory as contiguous starting with "RAM A BASE", "RAM B BASE", etc.
* however, RAM base registers can be skipped (e.g. A, B, C are set,
* D is skipped but E is set is okay).
*/
diff --git a/arch/ppc/syslib/hawk_common.c b/arch/ppc/syslib/hawk_common.c
index c5bf16b0d6a..86821d8753e 100644
--- a/arch/ppc/syslib/hawk_common.c
+++ b/arch/ppc/syslib/hawk_common.c
@@ -165,7 +165,7 @@ hawk_init(struct pci_controller *hose,
processor_pci_mem_start +
hose->mem_space.start) | 0x0);
- /* Map MPIC into vitual memory */
+ /* Map MPIC into virtual memory */
OpenPIC_Addr = ioremap(processor_mpic_base, HAWK_MPIC_SIZE);
return 0;
@@ -176,7 +176,7 @@ hawk_init(struct pci_controller *hose,
* This assumes that PPCBug has initialized the memory controller (SMC)
* on the Falcon/HAWK correctly (i.e., it does no sanity checking).
* It also assumes that the memory base registers are set to configure the
- * memory as contigous starting with "RAM A BASE", "RAM B BASE", etc.
+ * memory as contiguous starting with "RAM A BASE", "RAM B BASE", etc.
* however, RAM base registers can be skipped (e.g. A, B, C are set,
* D is skipped but E is set is okay).
*/
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
index e3b586b1ede..fe860d52e2e 100644
--- a/arch/ppc/syslib/m82xx_pci.c
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -197,7 +197,7 @@ pq2ads_setup_pci(struct pci_controller *hose)
CPM high 0b0000
CPM middle 0b0001
CPM low 0b0010
- PCI reguest 0b0011
+ PCI request 0b0011
Reserved 0b0100
Reserved 0b0101
Internal Core 0b0110
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
index 2fc7c4150a1..437a294527a 100644
--- a/arch/ppc/syslib/mpc10x_common.c
+++ b/arch/ppc/syslib/mpc10x_common.c
@@ -432,7 +432,7 @@ mpc10x_bridge_init(struct pci_controller *hose,
phys_eumb_base);
}
- /* IRQ's are determined at runtime */
+ /* IRQs are determined at runtime */
ppc_sys_platform_devices[MPC10X_IIC1].resource[1].start = MPC10X_I2C_IRQ;
ppc_sys_platform_devices[MPC10X_IIC1].resource[1].end = MPC10X_I2C_IRQ;
ppc_sys_platform_devices[MPC10X_DMA0].resource[1].start = MPC10X_DMA0_IRQ;
@@ -646,7 +646,7 @@ void __init mpc10x_set_openpic(void)
openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020);
/* Skip reserved space and map Message Unit Interrupt (I2O) */
openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0);
- /* Skip reserved space and map Serial Interupts */
+ /* Skip reserved space and map Serial Interrupts */
openpic_set_sources(EPIC_IRQ_BASE + 4, 2, OpenPIC_Addr + 0x11120);
openpic_init(NUM_8259_INTERRUPTS);
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index 80c609019bd..ecfa2c0f8ba 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -252,7 +252,7 @@ mpc52xx_setup_cpu(void)
out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
/* Disable XLB pipelining */
- /* (cfr errate 292. We could do this only just before ATA PIO
+ /* (cfr errata 292. We could do this only just before ATA PIO
transaction and re-enable it after ...) */
out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index 31fb56593d1..c05ac87ece4 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -21,7 +21,7 @@
#include <asm/irq.h>
#include <asm/ppc_sys.h>
-/* We use offsets for IORESOURCE_MEM to do not set dependences at compile time.
+/* We use offsets for IORESOURCE_MEM to do not set dependencies at compile time.
* They will get fixed up by mach_mpc8xx_fixup
*/
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index a6f8b686ea8..8485a68cd47 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -490,7 +490,7 @@ static struct platform_device *mv64x60_pd_devs[] __initdata = {
/*
* mv64x60_init()
*
- * Initialze the bridge based on setting passed in via 'si'. The bridge
+ * Initialize the bridge based on setting passed in via 'si'. The bridge
* handle, 'bh', will be set so that it can be used to make subsequent
* calls to routines in this file.
*/
@@ -1704,7 +1704,7 @@ gt64260_disable_all_windows(struct mv64x60_handle *bh,
/*
* gt64260a_chip_specific_init()
*
- * Implement errata work arounds for the GT64260A.
+ * Implement errata workarounds for the GT64260A.
*/
static void __init
gt64260a_chip_specific_init(struct mv64x60_handle *bh,
@@ -1776,7 +1776,7 @@ gt64260a_chip_specific_init(struct mv64x60_handle *bh,
/*
* gt64260b_chip_specific_init()
*
- * Implement errata work arounds for the GT64260B.
+ * Implement errata workarounds for the GT64260B.
*/
static void __init
gt64260b_chip_specific_init(struct mv64x60_handle *bh,
@@ -2316,7 +2316,7 @@ mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base)
/*
* mv64360_chip_specific_init()
*
- * Implement errata work arounds for the MV64360.
+ * Implement errata workarounds for the MV64360.
*/
static void __init
mv64360_chip_specific_init(struct mv64x60_handle *bh,
@@ -2336,7 +2336,7 @@ mv64360_chip_specific_init(struct mv64x60_handle *bh,
/*
* mv64460_chip_specific_init()
*
- * Implement errata work arounds for the MV64460.
+ * Implement errata workarounds for the MV64460.
*/
static void __init
mv64460_chip_specific_init(struct mv64x60_handle *bh,
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
index 50c55622ece..491fe9a5722 100644
--- a/arch/ppc/syslib/ocp.c
+++ b/arch/ppc/syslib/ocp.c
@@ -27,7 +27,7 @@
* device model. The devices on the OCP bus are seeded by an
* an initial OCP device array created by the arch-specific
* Device entries can be added/removed/modified through OCP
- * helper functions to accomodate system and board-specific
+ * helper functions to accommodate system and board-specific
* parameters commonly found in embedded systems. OCP also
* provides a standard method for devices to describe extended
* attributes about themselves to the system. A standard access
diff --git a/arch/ppc/syslib/ppc403_pic.c b/arch/ppc/syslib/ppc403_pic.c
index 607ebd111d4..c3b7b8bfbcf 100644
--- a/arch/ppc/syslib/ppc403_pic.c
+++ b/arch/ppc/syslib/ppc403_pic.c
@@ -112,7 +112,7 @@ ppc4xx_pic_init(void)
/*
* Disable all external interrupts until they are
- * explicity requested.
+ * explicitly requested.
*/
ppc_cached_irq_mask[0] = 0;
diff --git a/arch/ppc/syslib/ppc405_pci.c b/arch/ppc/syslib/ppc405_pci.c
index d6d838b16da..9e9035693bf 100644
--- a/arch/ppc/syslib/ppc405_pci.c
+++ b/arch/ppc/syslib/ppc405_pci.c
@@ -137,7 +137,7 @@ ppc4xx_find_bridges(void)
hose_a->pci_mem_offset = 0;
/* Setup bridge memory/IO ranges & resources
- * TODO: Handle firmwares setting up a legacy ISA mem base
+ * TODO: Handle firmware setting up a legacy ISA mem base
*/
hose_a->io_space.start = PPC405_PCI_LOWER_IO;
hose_a->io_space.end = PPC405_PCI_UPPER_IO;
diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c
index 1eef4ffed4f..bd301868996 100644
--- a/arch/ppc/syslib/ppc4xx_dma.c
+++ b/arch/ppc/syslib/ppc4xx_dma.c
@@ -241,7 +241,7 @@ ppc4xx_set_dma_count(unsigned int dmanr, unsigned int count)
}
/*
- * Returns the number of bytes left to be transfered.
+ * Returns the number of bytes left to be transferred.
* After a DMA transfer, this should return zero.
* Reading this while a DMA transfer is still in progress will return
* unpredictable results.
diff --git a/arch/ppc/syslib/ppc85xx_rio.c b/arch/ppc/syslib/ppc85xx_rio.c
index 2b097800cdd..af2425e4655 100644
--- a/arch/ppc/syslib/ppc85xx_rio.c
+++ b/arch/ppc/syslib/ppc85xx_rio.c
@@ -349,7 +349,7 @@ EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
* @dev_instance: Pointer to interrupt-specific data
*
* Handles outbound message interrupts. Executes a register outbound
- * mailbox event handler and acks the interrupt occurence.
+ * mailbox event handler and acks the interrupt occurrence.
*/
static irqreturn_t
mpc85xx_rio_tx_handler(int irq, void *dev_instance)
@@ -516,7 +516,7 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
* @dev_instance: Pointer to interrupt-specific data
*
* Handles inbound message interrupts. Executes a registered inbound
- * mailbox event handler and acks the interrupt occurence.
+ * mailbox event handler and acks the interrupt occurrence.
*/
static irqreturn_t
mpc85xx_rio_rx_handler(int irq, void *dev_instance)
diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
index 6fd4cdbada7..3b82333e96d 100644
--- a/arch/ppc/syslib/xilinx_pic.c
+++ b/arch/ppc/syslib/xilinx_pic.c
@@ -130,7 +130,7 @@ ppc4xx_pic_init(void)
/*
* Disable all external interrupts until they are
- * explicity requested.
+ * explicitly requested.
*/
intc_out_be32(intc + IER, 0);
diff --git a/arch/s390/kernel/audit.c b/arch/s390/kernel/audit.c
index 0741d919339..d1c76fe10f2 100644
--- a/arch/s390/kernel/audit.c
+++ b/arch/s390/kernel/audit.c
@@ -23,6 +23,20 @@ static unsigned chattr_class[] = {
~0U
};
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+#ifdef CONFIG_COMPAT
+ if (arch == AUDIT_ARCH_S390)
+ return 1;
+#endif
+ return 0;
+}
+
int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_COMPAT
@@ -51,15 +65,18 @@ static int __init audit_classes_init(void)
extern __u32 s390_write_class[];
extern __u32 s390_read_class[];
extern __u32 s390_chattr_class[];
+ extern __u32 s390_signal_class[];
audit_register_class(AUDIT_CLASS_WRITE_32, s390_write_class);
audit_register_class(AUDIT_CLASS_READ_32, s390_read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE_32, s390_dir_class);
audit_register_class(AUDIT_CLASS_CHATTR_32, s390_chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL_32, s390_signal_class);
#endif
audit_register_class(AUDIT_CLASS_WRITE, write_class);
audit_register_class(AUDIT_CLASS_READ, read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
return 0;
}
diff --git a/arch/s390/kernel/compat_audit.c b/arch/s390/kernel/compat_audit.c
index 16d9436bfa9..0569f5126e4 100644
--- a/arch/s390/kernel/compat_audit.c
+++ b/arch/s390/kernel/compat_audit.c
@@ -21,6 +21,11 @@ unsigned s390_read_class[] = {
~0U
};
+unsigned s390_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
int s390_classify_syscall(unsigned syscall)
{
switch(syscall) {
diff --git a/arch/sparc/kernel/auxio.c b/arch/sparc/kernel/auxio.c
index 118f3eca373..baf4ed3fb0f 100644
--- a/arch/sparc/kernel/auxio.c
+++ b/arch/sparc/kernel/auxio.c
@@ -88,7 +88,7 @@ void set_auxio(unsigned char bits_on, unsigned char bits_off)
break;
case sun4m:
if(!auxio_register)
- break; /* VME chassic sun4m, no auxio. */
+ break; /* VME chassis sun4m, no auxio. */
regval = sbus_readb(auxio_register);
sbus_writeb(((regval | bits_on) & ~bits_off) | AUXIO_ORMEIN4M,
auxio_register);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 987ec6782f9..62182d2d7b0 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -617,7 +617,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
* size must be the same as what as passed into pci_alloc_consistent,
* and likewise dma_addr must be the same as what *dma_addrp was set to.
*
- * References to the memory and mappings assosciated with cpu_addr/dma_addr
+ * References to the memory and mappings associated with cpu_addr/dma_addr
* past this call are illegal.
*/
void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba)
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index bdbefa8a974..f257a67bcf9 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -1,6 +1,6 @@
/* $Id: irq.c,v 1.114 2001/12/11 04:55:51 davem Exp $
* arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
- * Sparc the IRQ's are basically 'cast in stone'
+ * Sparc the IRQs are basically 'cast in stone'
* and you are supposed to probe the prom's device
* node trees to find out who's got which IRQ.
*
@@ -330,7 +330,7 @@ void handler_irq(int irq, struct pt_regs * regs)
irq_enter();
disable_pil_irq(irq);
#ifdef CONFIG_SMP
- /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */
+ /* Only rotate on lower priority IRQs (scsi, ethernet, etc.). */
if((sparc_cpu_model==sun4m) && (irq < 10))
smp4m_irq_rotate(cpu);
#endif
@@ -371,7 +371,7 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
}
#endif
-/* Fast IRQ's on the Sparc can only have one routine attached to them,
+/* Fast IRQs on the Sparc can only have one routine attached to them,
* thus no sharing possible.
*/
int request_fast_irq(unsigned int irq,
@@ -608,7 +608,7 @@ void __init init_IRQ(void)
break;
default:
- prom_printf("Cannot initialize IRQ's on this Sun machine...");
+ prom_printf("Cannot initialize IRQs on this Sun machine...");
break;
}
btfixup();
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 5ca7e8f42bd..79177119690 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -755,7 +755,7 @@ void __init pci_time_init(void)
static __inline__ unsigned long do_gettimeoffset(void)
{
/*
- * We devide all to 100
+ * We divide all by 100
* to have microsecond resolution and to avoid overflow
*/
unsigned long count =
@@ -956,7 +956,7 @@ EXPORT_SYMBOL(pci_device_to_OF_node);
* Also, think for a moment about likes of floppy.c that
* include architecture specific parts. They may want to redefine ins/outs.
*
- * We do not use horroble macroses here because we want to
+ * We do not use horrible macros here because we want to
* advance pointer by sizeof(size).
*/
void outsb(unsigned long addr, const void *src, unsigned long count)
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 2940d2c1a77..8c37f8f5adb 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -683,7 +683,7 @@ out:
* NOTE! Only a kernel-only process(ie the swapper or direct descendants
* who haven't done an "execve()") should use this: it will work within
* a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
+ * not be freed until both the parent and the child have exited.
*/
pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 116d6a241ca..396797e20c3 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -521,7 +521,7 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
lvl14_save[2] += smp4d_ticker - real_irq_entry;
/* For SMP we use the level 14 ticker, however the bootup code
- * has copied the firmwares level 14 vector into boot cpu's
+ * has copied the firmware's level 14 vector into the boot cpu's
* trap table, we must fix this now or we get squashed.
*/
local_irq_save(flags);
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index a654c16f402..91a803ea88b 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -299,7 +299,7 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
/* For SMP we use the level 14 ticker, however the bootup code
- * has copied the firmwares level 14 vector into boot cpu's
+ * has copied the firmware's level 14 vector into the boot cpu's
* trap table, we must fix this now or we get squashed.
*/
local_irq_save(flags);
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index e3f5b8ed4c5..90b52d4dab9 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -80,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
+/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd
#ifdef CONFIG_SUNOS_EMUL
/* Now the SunOS syscall table. */
@@ -197,6 +197,7 @@ sunos_sys_table:
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys
-/*310*/ .long sunos_nosys
+/*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys
+ .long sunos_nosys
#endif
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c
index dc8b598bedb..27fdac99f79 100644
--- a/arch/sparc/prom/printf.c
+++ b/arch/sparc/prom/printf.c
@@ -5,7 +5,7 @@
* Copyright (c) 2002 Pete Zaitcev (zaitcev@yahoo.com)
*
* We used to warn all over the code: DO NOT USE prom_printf(),
- * and yet people do. Anton's banking code was outputing banks
+ * and yet people do. Anton's banking code was outputting banks
* with prom_printf for most of the 2.4 lifetime. Since an effective
* stick is not available, we deployed a carrot: an early printk
* through PROM by means of -p boot option. This ought to fix it.
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index ad8d6b256a7..831781cab27 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -226,9 +226,6 @@ config ARCH_SPARSEMEM_DEFAULT
def_bool y
select SPARSEMEM_STATIC
-config LARGE_ALLOCS
- def_bool y
-
source "mm/Kconfig"
config ISA
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 37c2d369565..585ef4fb759 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.21
-# Sun May 6 22:46:54 2007
+# Fri May 11 14:31:45 2007
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -9,6 +9,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_64BIT=y
CONFIG_MMU=y
+CONFIG_QUICKLIST=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
@@ -49,6 +50,7 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=18
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
# CONFIG_BLK_DEV_INITRD is not set
@@ -66,14 +68,20 @@ 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_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
#
# Loadable module support
@@ -137,7 +145,6 @@ CONFIG_HUGETLB_PAGE_SIZE_4MB=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
-CONFIG_LARGE_ALLOCS=y
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -148,6 +155,7 @@ CONFIG_SPARSEMEM_STATIC=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=1
CONFIG_SBUS=y
CONFIG_SBUSCHAR=y
CONFIG_SUN_AUXIO=y
@@ -305,6 +313,7 @@ CONFIG_NET_TCPPROBE=m
# CONFIG_WIRELESS_EXT is not set
# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
#
# Device Drivers
@@ -359,8 +368,10 @@ CONFIG_ATA_OVER_ETH=m
#
# Misc devices
#
+# CONFIG_PHANTOM 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
@@ -379,6 +390,7 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
@@ -386,6 +398,7 @@ CONFIG_BLK_DEV_IDECD=y
CONFIG_IDE_GENERIC=y
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 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
@@ -521,6 +534,7 @@ 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
@@ -533,6 +547,7 @@ CONFIG_DM_ZERO=m
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
#
@@ -629,6 +644,8 @@ CONFIG_BNX2=m
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
+# CONFIG_MLX4_CORE is not set
+CONFIG_MLX4_DEBUG=y
#
# Token Ring devices
@@ -642,6 +659,16 @@ CONFIG_BNX2=m
# CONFIG_WLAN_80211 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
+
+#
# Wan interfaces
#
# CONFIG_WAN is not set
@@ -711,11 +738,18 @@ CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_SERIAL=y
+# 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=y
CONFIG_INPUT_SPARCSPKR=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_UINPUT is not set
# CONFIG_INPUT_POLLDEV is not set
@@ -762,14 +796,9 @@ CONFIG_UNIX98_PTYS=y
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
CONFIG_RTC=y
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_DRM is not set
@@ -779,6 +808,7 @@ CONFIG_RTC=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
@@ -841,13 +871,10 @@ CONFIG_I2C_ALGOBIT=y
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
@@ -874,6 +901,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 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
@@ -901,23 +929,30 @@ CONFIG_HWMON=y
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
-# Digital Video Broadcasting Devices
+# Graphics support
#
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Graphics support
+# Display device support
#
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
CONFIG_FB_DDC=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
@@ -949,7 +984,10 @@ CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
# CONFIG_FB_XVR500 is not set
# CONFIG_FB_XVR2500 is not set
# CONFIG_FB_PCI is not set
@@ -972,10 +1010,6 @@ CONFIG_FONTS=y
CONFIG_FONT_SUN8x16=y
# CONFIG_FONT_SUN12x22 is not set
# CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
@@ -1083,6 +1117,7 @@ CONFIG_SND_ALI5451=m
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
#
# ALSA Sparc devices
@@ -1092,7 +1127,7 @@ CONFIG_SND_SUN_CS4231=m
# CONFIG_SND_SUN_DBRI is not set
#
-# SoC audio support
+# System on Chip audio support
#
# CONFIG_SND_SOC is not set
@@ -1178,37 +1213,10 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_LIBUSUAL is not set
#
-# USB Input Devices
-#
-# 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
#
@@ -1252,10 +1260,6 @@ CONFIG_USB_STORAGE=m
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
#
@@ -1299,14 +1303,6 @@ CONFIG_USB_STORAGE=m
#
#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
-#
# Misc Linux/SPARC drivers
#
CONFIG_SUN_OPENPROMIO=m
@@ -1486,11 +1482,9 @@ CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=18
CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1574,6 +1568,7 @@ CONFIG_CRYPTO_TEST=m
CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
@@ -1581,3 +1576,4 @@ CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sparc64/kernel/audit.c b/arch/sparc64/kernel/audit.c
index aef19cc2707..24d7f4b4178 100644
--- a/arch/sparc64/kernel/audit.c
+++ b/arch/sparc64/kernel/audit.c
@@ -23,6 +23,20 @@ static unsigned chattr_class[] = {
~0U
};
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+#ifdef CONFIG_SPARC32_COMPAT
+ if (arch == AUDIT_ARCH_SPARC)
+ return 1;
+#endif
+ return 0;
+}
+
int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_SPARC32_COMPAT
@@ -51,15 +65,18 @@ static int __init audit_classes_init(void)
extern __u32 sparc32_write_class[];
extern __u32 sparc32_read_class[];
extern __u32 sparc32_chattr_class[];
+ extern __u32 sparc32_signal_class[];
audit_register_class(AUDIT_CLASS_WRITE_32, sparc32_write_class);
audit_register_class(AUDIT_CLASS_READ_32, sparc32_read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE_32, sparc32_dir_class);
audit_register_class(AUDIT_CLASS_CHATTR_32, sparc32_chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL_32, sparc32_signal_class);
#endif
audit_register_class(AUDIT_CLASS_WRITE, write_class);
audit_register_class(AUDIT_CLASS_READ, read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
return 0;
}
diff --git a/arch/sparc64/kernel/compat_audit.c b/arch/sparc64/kernel/compat_audit.c
index cca96c91b78..c1979482aa9 100644
--- a/arch/sparc64/kernel/compat_audit.c
+++ b/arch/sparc64/kernel/compat_audit.c
@@ -20,6 +20,11 @@ unsigned sparc32_read_class[] = {
~0U
};
+unsigned sparc32_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
int sparc32_classify_syscall(unsigned syscall)
{
switch(syscall) {
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
index ec10f7edcf8..0e03c8e218c 100644
--- a/arch/sparc64/kernel/devices.c
+++ b/arch/sparc64/kernel/devices.c
@@ -21,7 +21,7 @@
#include <asm/timer.h>
#include <asm/cpudata.h>
-/* Used to synchronize acceses to NatSemi SUPER I/O chip configure
+/* Used to synchronize accesses to NatSemi SUPER I/O chip configure
* operations in asm/ns87303.h
*/
DEFINE_SPINLOCK(ns87303_lock);
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 9ac9a307999..7455f5d0551 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -596,7 +596,7 @@ static void __init build_device_resources(struct of_device *op,
/* Convert to num-entries. */
num_reg /= na + ns;
- /* Prevent overruning the op->resources[] array. */
+ /* Prevent overrunning the op->resources[] array. */
if (num_reg > PROMREG_MAX) {
printk(KERN_WARNING "%s: Too many regs (%d), "
"limiting to %d.\n",
@@ -904,7 +904,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
op->num_irqs = 0;
}
- /* Prevent overruning the op->irqs[] array. */
+ /* Prevent overrunning the op->irqs[] array. */
if (op->num_irqs > PROMINTR_MAX) {
printk(KERN_WARNING "%s: Too many irqs (%d), "
"limiting to %d.\n",
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index cf9a75112d0..d4c077dc5e8 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -495,8 +495,8 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p)
*last_p = last;
}
-static void __init pci_resource_adjust(struct resource *res,
- struct resource *root)
+static void pci_resource_adjust(struct resource *res,
+ struct resource *root)
{
res->start += root->start;
res->end += root->start;
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c
index 9198c1a0f7a..7f5d473901c 100644
--- a/arch/sparc64/kernel/pci_fire.c
+++ b/arch/sparc64/kernel/pci_fire.c
@@ -37,7 +37,7 @@ static void pci_fire_scan_bus(struct pci_pbm_info *pbm)
#define FIRE_IOMMU_CONTROL 0x40000UL
#define FIRE_IOMMU_TSBBASE 0x40008UL
#define FIRE_IOMMU_FLUSH 0x40100UL
-#define FIRE_IOMMU_FLUSHINV 0x40100UL
+#define FIRE_IOMMU_FLUSHINV 0x40108UL
static void pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm)
{
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index dfd6f9f4790..70d2364fdfe 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -542,7 +542,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
/* Map a set of buffers described by SGLIST with NELEMS array
* elements in streaming mode for PCI DMA.
* When making changes here, inspect the assembly output. I was having
- * hard time to kepp this routine out of using stack slots for holding variables.
+ * hard time to keep this routine out of using stack slots for holding variables.
*/
static int pci_4u_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int direction)
{
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 34df4047587..044e8ec4c0f 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -731,7 +731,7 @@ struct pci_sun4v_msiq_entry {
u64 msi_address;
- /* The format of this value is message type dependant.
+ /* The format of this value is message type dependent.
* For MSI bits 15:0 are the data from the MSI packet.
* For MSI-X bits 31:0 are the data from the MSI packet.
* For MSG, the message code and message routing code where:
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 8e3c6e43511..952762bfb4c 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -677,7 +677,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
* NOTE! Only a kernel-only process(ie the swapper or direct descendants
* who haven't done an "execve()") should use this: it will work within
* a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
+ * not be freed until both the parent and the child have exited.
*/
pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index b7976b14d0b..02830e4671f 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -899,7 +899,7 @@ static unsigned int fire_irq_build(struct device_node *dp,
/* The interrupt map registers do not have an INO field
* like other chips do. They return zero in the INO
* field, and the interrupt controller number is controlled
- * in bits 6 thru 9. So in order for build_irq() to get
+ * in bits 6 to 9. So in order for build_irq() to get
* the INO right we pass it in as part of the fixup
* which will get added to the map register zero value
* read by build_irq().
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 5fe7f9ad4a9..8765e32155a 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -81,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
+/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd
#endif /* CONFIG_COMPAT */
@@ -153,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
+/*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 +271,7 @@ sunos_sys_table:
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys
-/*310*/ .long sunos_nosys
+/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys
+ .word sunos_nosys
#endif
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 259063f41f9..6b9a06e4254 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -55,6 +55,7 @@ DEFINE_SPINLOCK(rtc_lock);
void __iomem *mstk48t02_regs = NULL;
#ifdef CONFIG_PCI
unsigned long ds1287_regs = 0UL;
+static void __iomem *bq4802_regs;
#endif
static void __iomem *mstk48t08_regs;
@@ -565,12 +566,14 @@ static void __init set_system_time(void)
void __iomem *mregs = mstk48t02_regs;
#ifdef CONFIG_PCI
unsigned long dregs = ds1287_regs;
+ void __iomem *bregs = bq4802_regs;
#else
unsigned long dregs = 0UL;
+ void __iomem *bregs = 0UL;
#endif
u8 tmp;
- if (!mregs && !dregs) {
+ if (!mregs && !dregs && !bregs) {
prom_printf("Something wrong, clock regs not mapped yet.\n");
prom_halt();
}
@@ -589,6 +592,33 @@ static void __init set_system_time(void)
day = MSTK_REG_DOM(mregs);
mon = MSTK_REG_MONTH(mregs);
year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
+ } else if (bregs) {
+ unsigned char val = readb(bregs + 0x0e);
+ unsigned int century;
+
+ /* BQ4802 RTC chip. */
+
+ writeb(val | 0x08, bregs + 0x0e);
+
+ sec = readb(bregs + 0x00);
+ min = readb(bregs + 0x02);
+ hour = readb(bregs + 0x04);
+ day = readb(bregs + 0x06);
+ mon = readb(bregs + 0x09);
+ year = readb(bregs + 0x0a);
+ century = readb(bregs + 0x0f);
+
+ writeb(val, bregs + 0x0e);
+
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ BCD_TO_BIN(century);
+
+ year += (century * 100);
} else {
/* Dallas 12887 RTC chip. */
@@ -712,7 +742,8 @@ static int __init clock_model_matches(const char *model)
strcmp(model, "m5819") &&
strcmp(model, "m5819p") &&
strcmp(model, "m5823") &&
- strcmp(model, "ds1287"))
+ strcmp(model, "ds1287") &&
+ strcmp(model, "bq4802"))
return 0;
return 1;
@@ -722,9 +753,13 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
{
struct device_node *dp = op->node;
const char *model = of_get_property(dp, "model", NULL);
+ const char *compat = of_get_property(dp, "compatible", NULL);
unsigned long size, flags;
void __iomem *regs;
+ if (!model)
+ model = compat;
+
if (!model || !clock_model_matches(model))
return -ENODEV;
@@ -746,6 +781,8 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
!strcmp(model, "m5819p") ||
!strcmp(model, "m5823")) {
ds1287_regs = (unsigned long) regs;
+ } else if (!strcmp(model, "bq4802")) {
+ bq4802_regs = regs;
} else
#endif
if (model[5] == '0' && model[6] == '2') {
@@ -1070,8 +1107,10 @@ static int set_rtc_mmss(unsigned long nowtime)
void __iomem *mregs = mstk48t02_regs;
#ifdef CONFIG_PCI
unsigned long dregs = ds1287_regs;
+ void __iomem *bregs = bq4802_regs;
#else
unsigned long dregs = 0UL;
+ void __iomem *bregs = 0UL;
#endif
unsigned long flags;
u8 tmp;
@@ -1080,7 +1119,7 @@ static int set_rtc_mmss(unsigned long nowtime)
* Not having a register set can lead to trouble.
* Also starfire doesn't have a tod clock.
*/
- if (!mregs && !dregs)
+ if (!mregs && !dregs & !bregs)
return -1;
if (mregs) {
@@ -1129,6 +1168,37 @@ static int set_rtc_mmss(unsigned long nowtime)
return -1;
}
+ } else if (bregs) {
+ int retval = 0;
+ unsigned char val = readb(bregs + 0x0e);
+
+ /* BQ4802 RTC chip. */
+
+ writeb(val | 0x08, bregs + 0x0e);
+
+ chip_minutes = readb(bregs + 0x02);
+ BCD_TO_BIN(chip_minutes);
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+ if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
+ real_minutes += 30;
+ real_minutes %= 60;
+
+ if (abs(real_minutes - chip_minutes) < 30) {
+ BIN_TO_BCD(real_seconds);
+ BIN_TO_BCD(real_minutes);
+ writeb(real_seconds, bregs + 0x00);
+ writeb(real_minutes, bregs + 0x02);
+ } else {
+ printk(KERN_WARNING
+ "set_rtc_mmss: can't update from %d to %d\n",
+ chip_minutes, real_minutes);
+ retval = -1;
+ }
+
+ writeb(val, bregs + 0x0e);
+
+ return retval;
} else {
int retval = 0;
unsigned char save_control, save_freq_select;
@@ -1259,38 +1329,152 @@ static void to_tm(int tim, struct rtc_time *tm)
/* Both Starfire and SUN4V give us seconds since Jan 1st, 1970,
* aka Unix time. So we have to convert to/from rtc_time.
*/
-static inline void mini_get_rtc_time(struct rtc_time *time)
+static void starfire_get_rtc_time(struct rtc_time *time)
{
- unsigned long flags;
- u32 seconds;
+ u32 seconds = starfire_get_time();
- spin_lock_irqsave(&rtc_lock, flags);
- seconds = 0;
- if (this_is_starfire)
- seconds = starfire_get_time();
- else if (tlb_type == hypervisor)
- seconds = hypervisor_get_time();
- spin_unlock_irqrestore(&rtc_lock, flags);
+ to_tm(seconds, time);
+ time->tm_year -= 1900;
+ time->tm_mon -= 1;
+}
+
+static int starfire_set_rtc_time(struct rtc_time *time)
+{
+ u32 seconds = mktime(time->tm_year + 1900, time->tm_mon + 1,
+ time->tm_mday, time->tm_hour,
+ time->tm_min, time->tm_sec);
+
+ return starfire_set_time(seconds);
+}
+
+static void hypervisor_get_rtc_time(struct rtc_time *time)
+{
+ u32 seconds = hypervisor_get_time();
to_tm(seconds, time);
time->tm_year -= 1900;
time->tm_mon -= 1;
}
-static inline int mini_set_rtc_time(struct rtc_time *time)
+static int hypervisor_set_rtc_time(struct rtc_time *time)
{
u32 seconds = mktime(time->tm_year + 1900, time->tm_mon + 1,
time->tm_mday, time->tm_hour,
time->tm_min, time->tm_sec);
+
+ return hypervisor_set_time(seconds);
+}
+
+static void bq4802_get_rtc_time(struct rtc_time *time)
+{
+ unsigned char val = readb(bq4802_regs + 0x0e);
+ unsigned int century;
+
+ writeb(val | 0x08, bq4802_regs + 0x0e);
+
+ time->tm_sec = readb(bq4802_regs + 0x00);
+ time->tm_min = readb(bq4802_regs + 0x02);
+ time->tm_hour = readb(bq4802_regs + 0x04);
+ time->tm_mday = readb(bq4802_regs + 0x06);
+ time->tm_mon = readb(bq4802_regs + 0x09);
+ time->tm_year = readb(bq4802_regs + 0x0a);
+ time->tm_wday = readb(bq4802_regs + 0x08);
+ century = readb(bq4802_regs + 0x0f);
+
+ writeb(val, bq4802_regs + 0x0e);
+
+ BCD_TO_BIN(time->tm_sec);
+ BCD_TO_BIN(time->tm_min);
+ BCD_TO_BIN(time->tm_hour);
+ BCD_TO_BIN(time->tm_mday);
+ BCD_TO_BIN(time->tm_mon);
+ BCD_TO_BIN(time->tm_year);
+ BCD_TO_BIN(time->tm_wday);
+ BCD_TO_BIN(century);
+
+ time->tm_year += (century * 100);
+ time->tm_year -= 1900;
+
+ time->tm_mon--;
+}
+
+static int bq4802_set_rtc_time(struct rtc_time *time)
+{
+ unsigned char val = readb(bq4802_regs + 0x0e);
+ unsigned char sec, min, hrs, day, mon, yrs, century;
+ unsigned int year;
+
+ year = time->tm_year + 1900;
+ century = year / 100;
+ yrs = year % 100;
+
+ mon = time->tm_mon + 1; /* tm_mon starts at zero */
+ day = time->tm_mday;
+ hrs = time->tm_hour;
+ min = time->tm_min;
+ sec = time->tm_sec;
+
+ BIN_TO_BCD(sec);
+ BIN_TO_BCD(min);
+ BIN_TO_BCD(hrs);
+ BIN_TO_BCD(day);
+ BIN_TO_BCD(mon);
+ BIN_TO_BCD(yrs);
+ BIN_TO_BCD(century);
+
+ writeb(val | 0x08, bq4802_regs + 0x0e);
+
+ writeb(sec, bq4802_regs + 0x00);
+ writeb(min, bq4802_regs + 0x02);
+ writeb(hrs, bq4802_regs + 0x04);
+ writeb(day, bq4802_regs + 0x06);
+ writeb(mon, bq4802_regs + 0x09);
+ writeb(yrs, bq4802_regs + 0x0a);
+ writeb(century, bq4802_regs + 0x0f);
+
+ writeb(val, bq4802_regs + 0x0e);
+
+ return 0;
+}
+
+struct mini_rtc_ops {
+ void (*get_rtc_time)(struct rtc_time *);
+ int (*set_rtc_time)(struct rtc_time *);
+};
+
+static struct mini_rtc_ops starfire_rtc_ops = {
+ .get_rtc_time = starfire_get_rtc_time,
+ .set_rtc_time = starfire_set_rtc_time,
+};
+
+static struct mini_rtc_ops hypervisor_rtc_ops = {
+ .get_rtc_time = hypervisor_get_rtc_time,
+ .set_rtc_time = hypervisor_set_rtc_time,
+};
+
+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 *mini_rtc_ops;
+
+static inline void mini_get_rtc_time(struct rtc_time *time)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ mini_rtc_ops->get_rtc_time(time);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+}
+
+static inline int mini_set_rtc_time(struct rtc_time *time)
+{
unsigned long flags;
int err;
spin_lock_irqsave(&rtc_lock, flags);
- err = -ENODEV;
- if (this_is_starfire)
- err = starfire_set_time(seconds);
- else if (tlb_type == hypervisor)
- err = hypervisor_set_time(seconds);
+ err = mini_rtc_ops->set_rtc_time(time);
spin_unlock_irqrestore(&rtc_lock, flags);
return err;
@@ -1391,7 +1575,13 @@ static int __init rtc_mini_init(void)
{
int retval;
- if (tlb_type != hypervisor && !this_is_starfire)
+ if (tlb_type == hypervisor)
+ mini_rtc_ops = &hypervisor_rtc_ops;
+ else if (this_is_starfire)
+ mini_rtc_ops = &starfire_rtc_ops;
+ else if (bq4802_regs)
+ mini_rtc_ops = &bq4802_rtc_ops;
+ else
return -ENODEV;
printk(KERN_INFO "Mini RTC Driver\n");
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index d7004eaf1c8..6e5b01d779d 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1008,7 +1008,7 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
if (initrd_start) {
size = initrd_end - initrd_start;
- /* Resert the initrd image area. */
+ /* Reserve the initrd image area. */
#ifdef CONFIG_DEBUG_BOOTMEM
prom_printf("reserve_bootmem(initrd): base[%llx] size[%lx]\n",
initrd_start, initrd_end);
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index b9c0f307a8f..c504312219b 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -277,7 +277,8 @@ config HIGHMEM
config KERNEL_STACK_ORDER
int "Kernel stack size order"
- default 2
+ default 1 if 64BIT
+ default 0 if !64BIT
help
This option determines the size of UML kernel stacks. They will
be 1 << order pages. The default is OK unless you're running Valgrind
diff --git a/arch/um/defconfig b/arch/um/defconfig
index f938fa82214..a54d0efecae 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -86,7 +86,7 @@ CONFIG_MCONSOLE=y
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_NEST_LEVEL=0
# CONFIG_HIGHMEM is not set
-CONFIG_KERNEL_STACK_ORDER=2
+CONFIG_KERNEL_STACK_ORDER=0
CONFIG_UML_REAL_TIME_CLOCK=y
#
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 5593a802708..541f4a8ca51 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -28,3 +28,5 @@ DEFINE(UM_NR_CPUS, NR_CPUS);
/* For crypto assembler code. */
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
+
+DEFINE(UM_THREAD_SIZE, THREAD_SIZE);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 50a49691e0e..8d7f7c1cb9c 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -117,4 +117,7 @@ extern void sigio_handler(int sig, union uml_pt_regs *regs);
extern void copy_sc(union uml_pt_regs *regs, void *from);
+unsigned long to_irq_stack(int sig, unsigned long *mask_out);
+unsigned long from_irq_stack(int nested);
+
#endif
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 688d181b5f8..4d9fb26387d 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -272,7 +272,6 @@ extern void do_longjmp(void *p, int val);
/* util.c */
extern void stack_protections(unsigned long address);
-extern void task_protections(unsigned long address);
extern int raw(int fd);
extern void setup_machinename(char *machine_out);
extern void setup_hostinfo(char *buf, int len);
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index e36f92b463c..87a4e4427d8 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -97,6 +97,8 @@ SECTIONS
.data : {
. = ALIGN(KERNEL_STACK_SIZE); /* init_task */
*(.data.init_task)
+ . = ALIGN(KERNEL_STACK_SIZE);
+ *(.data.init_irqstack)
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index cda91aa8e70..d4f1d1ab252 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,intel.linux}.com)
* Licensed under the GPL
*/
@@ -33,28 +33,20 @@ EXPORT_SYMBOL(init_task);
/*
* Initial thread structure.
*
- * We need to make sure that this is 16384-byte aligned due to the
+ * We need to make sure that this is aligned due to the
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
-union thread_union init_thread_union
-__attribute__((__section__(".data.init_task"))) =
-{ INIT_THREAD_INFO(init_task) };
+union thread_union init_thread_union
+ __attribute__((__section__(".data.init_task"))) =
+ { INIT_THREAD_INFO(init_task) };
+
+union thread_union cpu0_irqstack
+ __attribute__((__section__(".data.init_irqstack"))) =
+ { INIT_THREAD_INFO(init_task) };
void unprotect_stack(unsigned long stack)
{
- os_protect_memory((void *) stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
- 1, 1, 0);
+ os_protect_memory((void *) stack, THREAD_SIZE, 1, 1, 0);
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 8f2ed369031..dba04d88b43 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
* Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
@@ -32,6 +32,7 @@
#include "sigio.h"
#include "um_malloc.h"
#include "misc_constants.h"
+#include "as-layout.h"
/*
* Generic, controller-independent functions:
@@ -53,7 +54,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (i < NR_IRQS) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
- if (!action)
+ if (!action)
goto skip;
seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
@@ -468,3 +469,113 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
out:
return err;
}
+
+/*
+ * IRQ stack entry and exit:
+ *
+ * Unlike i386, UML doesn't receive IRQs on the normal kernel stack
+ * and switch over to the IRQ stack after some preparation. We use
+ * sigaltstack to receive signals on a separate stack from the start.
+ * These two functions make sure the rest of the kernel won't be too
+ * upset by being on a different stack. The IRQ stack has a
+ * thread_info structure at the bottom so that current et al continue
+ * to work.
+ *
+ * to_irq_stack copies the current task's thread_info to the IRQ stack
+ * thread_info and sets the tasks's stack to point to the IRQ stack.
+ *
+ * from_irq_stack copies the thread_info struct back (flags may have
+ * been modified) and resets the task's stack pointer.
+ *
+ * Tricky bits -
+ *
+ * What happens when two signals race each other? UML doesn't block
+ * signals with sigprocmask, SA_DEFER, or sa_mask, so a second signal
+ * could arrive while a previous one is still setting up the
+ * thread_info.
+ *
+ * There are three cases -
+ * The first interrupt on the stack - sets up the thread_info and
+ * handles the interrupt
+ * A nested interrupt interrupting the copying of the thread_info -
+ * can't handle the interrupt, as the stack is in an unknown state
+ * A nested interrupt not interrupting the copying of the
+ * thread_info - doesn't do any setup, just handles the interrupt
+ *
+ * The first job is to figure out whether we interrupted stack setup.
+ * This is done by xchging the signal mask with thread_info->pending.
+ * If the value that comes back is zero, then there is no setup in
+ * progress, and the interrupt can be handled. If the value is
+ * non-zero, then there is stack setup in progress. In order to have
+ * the interrupt handled, we leave our signal in the mask, and it will
+ * be handled by the upper handler after it has set up the stack.
+ *
+ * Next is to figure out whether we are the outer handler or a nested
+ * one. As part of setting up the stack, thread_info->real_thread is
+ * set to non-NULL (and is reset to NULL on exit). This is the
+ * nesting indicator. If it is non-NULL, then the stack is already
+ * set up and the handler can run.
+ */
+
+static unsigned long pending_mask;
+
+unsigned long to_irq_stack(int sig, unsigned long *mask_out)
+{
+ struct thread_info *ti;
+ unsigned long mask, old;
+ int nested;
+
+ mask = xchg(&pending_mask, 1 << sig);
+ if(mask != 0){
+ /* If any interrupts come in at this point, we want to
+ * make sure that their bits aren't lost by our
+ * putting our bit in. So, this loop accumulates bits
+ * until xchg returns the same value that we put in.
+ * When that happens, there were no new interrupts,
+ * and pending_mask contains a bit for each interrupt
+ * that came in.
+ */
+ old = 1 << sig;
+ do {
+ old |= mask;
+ mask = xchg(&pending_mask, old);
+ } while(mask != old);
+ return 1;
+ }
+
+ ti = current_thread_info();
+ nested = (ti->real_thread != NULL);
+ if(!nested){
+ struct task_struct *task;
+ struct thread_info *tti;
+
+ task = cpu_tasks[ti->cpu].task;
+ tti = task_thread_info(task);
+ *ti = *tti;
+ ti->real_thread = tti;
+ task->stack = ti;
+ }
+
+ mask = xchg(&pending_mask, 0);
+ *mask_out |= mask | nested;
+ return 0;
+}
+
+unsigned long from_irq_stack(int nested)
+{
+ struct thread_info *ti, *to;
+ unsigned long mask;
+
+ ti = current_thread_info();
+
+ pending_mask = 1;
+
+ to = ti->real_thread;
+ current->stack = to;
+ ti->real_thread = NULL;
+ *to = *ti;
+
+ mask = xchg(&pending_mask, 0);
+ return mask & ~1;
+}
+
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index a96ae1a0610..2a69a7ce579 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -163,8 +163,12 @@ static int start_kernel_proc(void *unused)
extern int userspace_pid[];
+extern char cpu0_irqstack[];
+
int start_uml_skas(void)
{
+ stack_protections((unsigned long) &cpu0_irqstack);
+ set_sigstack(cpu0_irqstack, THREAD_SIZE);
if(proc_mm)
userspace_pid[0] = start_userspace(0);
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 98e21743e60..40126cb5180 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -57,7 +57,7 @@ void flush_thread_tt(void)
enable_timer();
free_page(stack);
protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
- task_protections((unsigned long) current_thread);
+ stack_protections((unsigned long) current_thread);
force_flush_all();
unblock_signals();
}
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index c631303cb80..74347adf81b 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -209,7 +209,7 @@ void finish_fork_handler(int sig)
if(current->mm != current->parent->mm)
protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
1, 0, 1);
- task_protections((unsigned long) current_thread);
+ stack_protections((unsigned long) current_thread);
free_page(current->thread.temp_stack);
local_irq_disable();
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 1cf954a47fd..ecc458fe51b 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -459,7 +459,7 @@ int __init linux_main(int argc, char **argv)
uml_postsetup();
- task_protections((unsigned long) &init_thread_info);
+ stack_protections((unsigned long) &init_thread_info);
os_flush_stdout();
return CHOOSE_MODE(start_uml_tt(), start_uml_skas());
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index f6301274cf3..bc59f97e34d 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -59,6 +59,8 @@ SECTIONS
{
. = ALIGN(KERNEL_STACK_SIZE); /* init_task */
*(.data.init_task)
+ . = ALIGN(KERNEL_STACK_SIZE);
+ *(.data.init_irqstack)
*(.data)
*(.gnu.linkonce.d*)
CONSTRUCTORS
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 48d49341530..18e5c8b67eb 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -61,15 +61,19 @@ void sig_handler(int sig, struct sigcontext *sc)
static void real_alarm_handler(int sig, struct sigcontext *sc)
{
+ union uml_pt_regs regs;
+
if(sig == SIGALRM)
switch_timers(0);
- CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
- sig, sc);
+ if(sc != NULL)
+ copy_sc(&regs, sc);
+ regs.skas.is_user = 0;
+ unblock_signals();
+ timer_handler(sig, &regs);
if(sig == SIGALRM)
switch_timers(1);
-
}
void alarm_handler(int sig, struct sigcontext *sc)
@@ -113,6 +117,46 @@ void remove_sigstack(void)
void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
+void handle_signal(int sig, struct sigcontext *sc)
+{
+ unsigned long pending = 0;
+
+ do {
+ int nested, bail;
+
+ /*
+ * pending comes back with one bit set for each
+ * interrupt that arrived while setting up the stack,
+ * plus a bit for this interrupt, plus the zero bit is
+ * set if this is a nested interrupt.
+ * If bail is true, then we interrupted another
+ * handler setting up the stack. In this case, we
+ * have to return, and the upper handler will deal
+ * with this interrupt.
+ */
+ bail = to_irq_stack(sig, &pending);
+ if(bail)
+ return;
+
+ nested = pending & 1;
+ pending &= ~1;
+
+ while((sig = ffs(pending)) != 0){
+ sig--;
+ pending &= ~(1 << sig);
+ (*handlers[sig])(sig, sc);
+ }
+
+ /* Again, pending comes back with a mask of signals
+ * that arrived while tearing down the stack. If this
+ * is non-zero, we just go back, set up the stack
+ * again, and handle the new interrupts.
+ */
+ if(!nested)
+ pending = from_irq_stack(nested);
+ } while(pending);
+}
+
extern void hard_handler(int sig);
void set_handler(int sig, void (*handler)(int), int flags, ...)
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 6a0e466d01e..f9d2f8545af 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -288,7 +288,8 @@ int start_userspace(unsigned long stub_stack)
void userspace(union uml_pt_regs *regs)
{
int err, status, op, pid = userspace_pid[0];
- int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
+ /* To prevent races if using_sysemu changes under us.*/
+ int local_using_sysemu;
while(1){
restore_registers(pid, regs);
@@ -296,7 +297,8 @@ void userspace(union uml_pt_regs *regs)
/* Now we set local_using_sysemu to be used for one loop */
local_using_sysemu = get_using_sysemu();
- op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
+ op = SELECT_PTRACE_OPERATION(local_using_sysemu,
+ singlestepping(NULL));
err = ptrace(op, pid, 0, 0);
if(err)
@@ -490,8 +492,8 @@ void map_stub_pages(int fd, unsigned long code,
void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
{
(*buf)[0].JB_IP = (unsigned long) handler;
- (*buf)[0].JB_SP = (unsigned long) stack +
- (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) - sizeof(void *);
+ (*buf)[0].JB_SP = (unsigned long) stack + UM_THREAD_SIZE -
+ sizeof(void *);
}
#define INIT_JMP_NEW_THREAD 0
@@ -533,8 +535,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
case INIT_JMP_NEW_THREAD:
(*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
(*switch_buf)[0].JB_SP = (unsigned long) stack +
- (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) -
- sizeof(void *);
+ UM_THREAD_SIZE - sizeof(void *);
break;
case INIT_JMP_CALLBACK:
(*cb_proc)(cb_arg);
diff --git a/arch/um/os-Linux/sys-i386/signal.c b/arch/um/os-Linux/sys-i386/signal.c
index 0d3eae51835..f311609f93d 100644
--- a/arch/um/os-Linux/sys-i386/signal.c
+++ b/arch/um/os-Linux/sys-i386/signal.c
@@ -1,15 +1,13 @@
/*
- * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <signal.h>
-extern void (*handlers[])(int sig, struct sigcontext *sc);
+extern void handle_signal(int sig, struct sigcontext *sc);
void hard_handler(int sig)
{
- struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
-
- (*handlers[sig])(sig, sc);
+ handle_signal(sig, (struct sigcontext *) (&sig + 1));
}
diff --git a/arch/um/os-Linux/sys-x86_64/signal.c b/arch/um/os-Linux/sys-x86_64/signal.c
index 3f369e5f976..82a388822cd 100644
--- a/arch/um/os-Linux/sys-x86_64/signal.c
+++ b/arch/um/os-Linux/sys-x86_64/signal.c
@@ -1,16 +1,16 @@
/*
- * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <signal.h>
-extern void (*handlers[])(int sig, struct sigcontext *sc);
+extern void handle_signal(int sig, struct sigcontext *sc);
void hard_handler(int sig)
{
struct ucontext *uc;
asm("movq %%rdx, %0" : "=r" (uc));
- (*handlers[sig])(sig, (struct sigcontext *) &uc->uc_mcontext);
+ handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext);
}
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index c307a89ed25..7cbcf484e13 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -33,25 +33,8 @@
void stack_protections(unsigned long address)
{
- int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-
- if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0)
- panic("protecting stack failed, errno = %d", errno);
-}
-
-void task_protections(unsigned long address)
-{
- unsigned long guard = address + UM_KERN_PAGE_SIZE;
- unsigned long stack = guard + UM_KERN_PAGE_SIZE;
- int prot = 0, pages;
-
-#ifdef notdef
- if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0)
- panic("protecting guard page failed, errno = %d", errno);
-#endif
- pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
- prot = PROT_READ | PROT_WRITE | PROT_EXEC;
- if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0)
+ if(mprotect((void *) address, UM_THREAD_SIZE,
+ PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
panic("protecting stack failed, errno = %d", errno);
}
@@ -72,7 +55,7 @@ int raw(int fd)
/* XXX tcsetattr could have applied only some changes
* (and cfmakeraw() is a set of changes) */
- return(0);
+ return 0;
}
void setup_machinename(char *machine_out)
diff --git a/arch/x86_64/ia32/audit.c b/arch/x86_64/ia32/audit.c
index 92d7d0c8d93..8850fe40ea3 100644
--- a/arch/x86_64/ia32/audit.c
+++ b/arch/x86_64/ia32/audit.c
@@ -20,6 +20,11 @@ unsigned ia32_read_class[] = {
~0U
};
+unsigned ia32_signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
int ia32_classify_syscall(unsigned syscall)
{
switch(syscall) {
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index f2106837827..21868f9bed7 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -716,4 +716,7 @@ ia32_sys_call_table:
.quad sys_getcpu
.quad sys_epoll_pwait
.quad compat_sys_utimensat /* 320 */
-ia32_syscall_end:
+ .quad compat_sys_signalfd
+ .quad compat_sys_timerfd
+ .quad sys_eventfd
+ia32_syscall_end:
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index a52af582059..a3d450d6c15 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -86,7 +86,7 @@ static int __init aperture_valid(u64 aper_base, u32 aper_size)
printk("Aperture too small (%d MB)\n", aper_size>>20);
return 0;
}
- if (aper_base + aper_size >= 0xffffffff) {
+ if (aper_base + aper_size > 0x100000000UL) {
printk("Aperture beyond 4GB. Ignoring.\n");
return 0;
}
diff --git a/arch/x86_64/kernel/audit.c b/arch/x86_64/kernel/audit.c
index 21f33387bef..06d3e5a14d9 100644
--- a/arch/x86_64/kernel/audit.c
+++ b/arch/x86_64/kernel/audit.c
@@ -23,6 +23,20 @@ static unsigned chattr_class[] = {
~0U
};
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+#ifdef CONFIG_IA32_EMULATION
+ if (arch == AUDIT_ARCH_I386)
+ return 1;
+#endif
+ return 0;
+}
+
int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_IA32_EMULATION
@@ -49,15 +63,18 @@ static int __init audit_classes_init(void)
extern __u32 ia32_write_class[];
extern __u32 ia32_read_class[];
extern __u32 ia32_chattr_class[];
+ extern __u32 ia32_signal_class[];
audit_register_class(AUDIT_CLASS_WRITE_32, ia32_write_class);
audit_register_class(AUDIT_CLASS_READ_32, ia32_read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE_32, ia32_dir_class);
audit_register_class(AUDIT_CLASS_CHATTR_32, ia32_chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL_32, ia32_signal_class);
#endif
audit_register_class(AUDIT_CLASS_WRITE, write_class);
audit_register_class(AUDIT_CLASS_READ, read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
return 0;
}
diff --git a/arch/x86_64/kernel/bugs.c b/arch/x86_64/kernel/bugs.c
index 12b585b5345..c3c6b91566e 100644
--- a/arch/x86_64/kernel/bugs.c
+++ b/arch/x86_64/kernel/bugs.c
@@ -9,10 +9,12 @@
#include <linux/init.h>
#include <asm/alternative.h>
#include <asm/processor.h>
+#include <asm/mtrr.h>
void __init check_bugs(void)
{
identify_cpu(&boot_cpu_data);
+ mtrr_bp_init();
#if !defined(CONFIG_SMP)
printk("CPU: ");
print_cpu_info(&boot_cpu_data);
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 213d90e0475..6c34bdd22e2 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -62,13 +62,6 @@ void __init x86_64_start_kernel(char * real_mode_data)
{
int i;
- /*
- * Make sure kernel is aligned to 2MB address. Catching it at compile
- * time is better. Change your config file and compile the kernel
- * for a 2MB aligned address (CONFIG_PHYSICAL_START)
- */
- BUILD_BUG_ON(CONFIG_PHYSICAL_START & (__KERNEL_ALIGN - 1));
-
/* clear bss before set_intr_gate with early_idt_handler */
clear_bss();
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 373ef66ca1d..ae091cdc1a4 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -476,7 +476,7 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
aper_base <<= 25;
aper_size = (32 * 1024 * 1024) << aper_order;
- if (aper_base + aper_size >= 0xffffffff || !aper_size)
+ if (aper_base + aper_size > 0x100000000UL || !aper_size)
aper_base = 0;
*size = aper_size;
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index db51577bda3..eb6524f3ac2 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -891,9 +891,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
#ifdef CONFIG_X86_MCE
mcheck_init(c);
#endif
- if (c == &boot_cpu_data)
- mtrr_bp_init();
- else
+ if (c != &boot_cpu_data)
mtrr_ap_init();
#ifdef CONFIG_NUMA
numa_add_cpu(smp_processor_id());
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 17e18897342..74a567afb83 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -3116,7 +3116,7 @@ static inline int should_fail_request(struct bio *bio)
* bi_sector for remaps as it sees fit. So the values of these fields
* should NOT be depended on after the call to generic_make_request.
*/
-void generic_make_request(struct bio *bio)
+static inline void __generic_make_request(struct bio *bio)
{
request_queue_t *q;
sector_t maxsector;
@@ -3215,6 +3215,57 @@ end_io:
} while (ret);
}
+/*
+ * We only want one ->make_request_fn to be active at a time,
+ * else stack usage with stacked devices could be a problem.
+ * So use current->bio_{list,tail} to keep a list of requests
+ * submited by a make_request_fn function.
+ * current->bio_tail is also used as a flag to say if
+ * generic_make_request is currently active in this task or not.
+ * If it is NULL, then no make_request is active. If it is non-NULL,
+ * then a make_request is active, and new requests should be added
+ * at the tail
+ */
+void generic_make_request(struct bio *bio)
+{
+ if (current->bio_tail) {
+ /* make_request is active */
+ *(current->bio_tail) = bio;
+ bio->bi_next = NULL;
+ current->bio_tail = &bio->bi_next;
+ return;
+ }
+ /* following loop may be a bit non-obvious, and so deserves some
+ * explanation.
+ * Before entering the loop, bio->bi_next is NULL (as all callers
+ * ensure that) so we have a list with a single bio.
+ * We pretend that we have just taken it off a longer list, so
+ * we assign bio_list to the next (which is NULL) and bio_tail
+ * to &bio_list, thus initialising the bio_list of new bios to be
+ * added. __generic_make_request may indeed add some more bios
+ * through a recursive call to generic_make_request. If it
+ * did, we find a non-NULL value in bio_list and re-enter the loop
+ * from the top. In this case we really did just take the bio
+ * of the top of the list (no pretending) and so fixup bio_list and
+ * bio_tail or bi_next, and call into __generic_make_request again.
+ *
+ * The loop was structured like this to make only one call to
+ * __generic_make_request (which is important as it is large and
+ * inlined) and to keep the structure simple.
+ */
+ BUG_ON(bio->bi_next);
+ do {
+ current->bio_list = bio->bi_next;
+ if (bio->bi_next == NULL)
+ current->bio_tail = &current->bio_list;
+ else
+ bio->bi_next = NULL;
+ __generic_make_request(bio);
+ bio = current->bio_list;
+ } while (bio);
+ current->bio_tail = NULL; /* deactivate */
+}
+
EXPORT_SYMBOL(generic_make_request);
/**
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index f031b873233..ad1f59c1b3f 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -2,11 +2,9 @@
# SATA/PATA driver configuration
#
-menu "Serial ATA (prod) and Parallel ATA (experimental) drivers"
+menuconfig ATA
+ tristate "Serial ATA (prod) and Parallel ATA (experimental) drivers"
depends on HAS_IOMEM
-
-config ATA
- tristate "ATA device support"
depends on BLOCK
depends on !(M32R || M68K) || BROKEN
depends on !SUN4 || BROKEN
@@ -24,6 +22,19 @@ config ATA_NONSTANDARD
bool
default n
+config ATA_ACPI
+ bool
+ depends on ACPI && PCI
+ default y
+ help
+ This option adds support for ATA-related ACPI objects.
+ These ACPI objects add the ability to retrieve taskfiles
+ from the ACPI BIOS and write them to the disk controller.
+ These objects may be related to performance, security,
+ power management, or other areas.
+ You can disable this at kernel boot time by using the
+ option libata.noacpi=1
+
config SATA_AHCI
tristate "AHCI SATA support"
depends on PCI
@@ -157,19 +168,6 @@ config SATA_INIC162X
help
This option enables support for Initio 162x Serial ATA.
-config SATA_ACPI
- bool
- depends on ACPI && PCI
- default y
- help
- This option adds support for SATA-related ACPI objects.
- These ACPI objects add the ability to retrieve taskfiles
- from the ACPI BIOS and write them to the disk controller.
- These objects may be related to performance, security,
- power management, or other areas.
- You can disable this at kernel boot time by using the
- option libata.noacpi=1
-
config PATA_ALI
tristate "ALi PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
@@ -585,6 +583,4 @@ config PATA_SCC
If unsure, say N.
-endif
-endmenu
-
+endif # ATA
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 6f42a0e2812..8149c68ac2c 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -69,4 +69,4 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o
-libata-$(CONFIG_SATA_ACPI) += libata-acpi.o
+libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index d9617892fc2..1ae443d7ab9 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -250,10 +250,6 @@ static struct scsi_host_template ahci_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations ahci_ops = {
@@ -400,6 +396,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 */
/* VIA */
{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 92a491ddd03..c3d753296bc 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -54,7 +54,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_ready(dev)) {
+ if (ata_dev_enabled(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->dma_mode = XFER_MW_DMA_0;
@@ -90,10 +90,6 @@ static struct scsi_host_template generic_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations generic_port_ops = {
@@ -145,7 +141,7 @@ static int all_generic_ide; /* Set to claim all devices */
static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
u16 command;
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &generic_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -153,7 +149,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
.udma_mask = 0x3f,
.port_ops = &generic_port_ops
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
/* Don't use the generic entry unless instructed to do so */
if (id->driver_data == 1 && all_generic_ide == 0)
@@ -179,7 +175,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
if (dev->vendor == PCI_VENDOR_ID_AL)
ata_pci_clear_simplex(dev);
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
static struct pci_device_id ata_generic[] = {
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 4a795fdb6a0..13b6b1df2ac 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -275,10 +275,6 @@ static struct scsi_host_template piix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations piix_pata_ops = {
@@ -1034,7 +1030,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
struct device *dev = &pdev->dev;
struct ata_port_info port_info[2];
- struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
+ const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] };
struct piix_host_priv *hpriv;
unsigned long port_flags;
@@ -1093,7 +1089,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
port_info[1].mwdma_mask = 0;
port_info[1].udma_mask = 0;
}
- return ata_pci_init_one(pdev, ppinfo, 2);
+ return ata_pci_init_one(pdev, ppi);
}
static int __init piix_init(void)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index cb3eab6e379..ed4138e24b0 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -270,8 +270,7 @@ out:
/**
* do_drive_get_GTF - get the drive bootup default taskfile settings
- * @ap: the ata_port for the drive
- * @ix: target ata_device (drive) index
+ * @dev: target ATA device
* @gtf_length: number of bytes of _GTF data returned at @gtf_address
* @gtf_address: buffer containing _GTF taskfile arrays
*
@@ -286,20 +285,19 @@ out:
* The returned @gtf_length and @gtf_address are only valid if the
* function return value is 0.
*/
-static int do_drive_get_GTF(struct ata_port *ap, int ix,
- unsigned int *gtf_length, unsigned long *gtf_address,
- unsigned long *obj_loc)
+static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
+ unsigned long *gtf_address, unsigned long *obj_loc)
{
- acpi_status status;
- acpi_handle dev_handle = NULL;
- acpi_handle chan_handle, drive_handle;
- acpi_integer pcidevfn = 0;
- u32 dev_adr;
- struct acpi_buffer output;
- union acpi_object *out_obj;
- struct device *dev = ap->host->dev;
- struct ata_device *atadev = &ap->device[ix];
- int err = -ENODEV;
+ struct ata_port *ap = dev->ap;
+ acpi_status status;
+ acpi_handle dev_handle = NULL;
+ acpi_handle chan_handle, drive_handle;
+ acpi_integer pcidevfn = 0;
+ u32 dev_adr;
+ struct acpi_buffer output;
+ union acpi_object *out_obj;
+ struct device *gdev = ap->host->dev;
+ int err = -ENODEV;
*gtf_length = 0;
*gtf_address = 0UL;
@@ -309,14 +307,14 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
return 0;
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+ ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
__FUNCTION__, ap->port_no);
- if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED)) {
+ if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED)) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: ERR: "
+ ata_dev_printk(dev, KERN_DEBUG, "%s: ERR: "
"ata_dev_present: %d, PORT_DISABLED: %lu\n",
- __FUNCTION__, ata_dev_enabled(atadev),
+ __FUNCTION__, ata_dev_enabled(dev),
ap->flags & ATA_FLAG_DISABLED);
goto out;
}
@@ -324,19 +322,19 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
/* Don't continue if device has no _ADR method.
* _GTF is intended for known motherboard devices. */
if (!(ap->cbl == ATA_CBL_SATA)) {
- err = pata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+ err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
if (err < 0) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: pata_get_dev_handle failed (%d)\n",
__FUNCTION__, err);
goto out;
}
} else {
- err = sata_get_dev_handle(dev, &dev_handle, &pcidevfn);
+ err = sata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
if (err < 0) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: sata_get_dev_handle failed (%d\n",
__FUNCTION__, err);
goto out;
@@ -344,7 +342,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
}
/* Get this drive's _ADR info. if not already known. */
- if (!atadev->obj_handle) {
+ if (!dev->obj_handle) {
if (!(ap->cbl == ATA_CBL_SATA)) {
/* get child objects of dev_handle == channel objects,
* + _their_ children == drive objects */
@@ -352,7 +350,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
chan_handle = acpi_get_child(dev_handle,
ap->port_no);
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: chan adr=%d: chan_handle=0x%p\n",
__FUNCTION__, ap->port_no,
chan_handle);
@@ -361,26 +359,26 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
goto out;
}
/* TBD: could also check ACPI object VALID bits */
- drive_handle = acpi_get_child(chan_handle, ix);
+ drive_handle = acpi_get_child(chan_handle, dev->devno);
if (!drive_handle) {
err = -ENODEV;
goto out;
}
- dev_adr = ix;
- atadev->obj_handle = drive_handle;
+ dev_adr = dev->devno;
+ dev->obj_handle = drive_handle;
} else { /* for SATA mode */
dev_adr = SATA_ADR_RSVD;
- err = get_sata_adr(dev, dev_handle, pcidevfn, 0,
- ap, atadev, &dev_adr);
+ err = get_sata_adr(gdev, dev_handle, pcidevfn, 0,
+ ap, dev, &dev_adr);
}
if (err < 0 || dev_adr == SATA_ADR_RSVD ||
- !atadev->obj_handle) {
+ !dev->obj_handle) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: get_sata/pata_adr failed: "
"err=%d, dev_adr=%u, obj_handle=0x%p\n",
__FUNCTION__, err, dev_adr,
- atadev->obj_handle);
+ dev->obj_handle);
goto out;
}
}
@@ -391,11 +389,11 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
/* _GTF has no input parameters */
err = -EIO;
- status = acpi_evaluate_object(atadev->obj_handle, "_GTF",
+ status = acpi_evaluate_object(dev->obj_handle, "_GTF",
NULL, &output);
if (ACPI_FAILURE(status)) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: Run _GTF error: status = 0x%x\n",
__FUNCTION__, status);
goto out;
@@ -403,7 +401,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
if (!output.length || !output.pointer) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+ ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
"length or ptr is NULL (0x%llx, 0x%p)\n",
__FUNCTION__,
(unsigned long long)output.length,
@@ -416,7 +414,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
if (out_obj->type != ACPI_TYPE_BUFFER) {
kfree(output.pointer);
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: Run _GTF: "
+ ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: "
"error: expected object type of "
" ACPI_TYPE_BUFFER, got 0x%x\n",
__FUNCTION__, out_obj->type);
@@ -427,7 +425,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
out_obj->buffer.length % REGS_PER_GTF) {
if (ata_msg_drv(ap))
- ata_dev_printk(atadev, KERN_ERR,
+ ata_dev_printk(dev, KERN_ERR,
"%s: unexpected GTF length (%d) or addr (0x%p)\n",
__FUNCTION__, out_obj->buffer.length,
out_obj->buffer.pointer);
@@ -439,7 +437,7 @@ static int do_drive_get_GTF(struct ata_port *ap, int ix,
*gtf_address = (unsigned long)out_obj->buffer.pointer;
*obj_loc = (unsigned long)out_obj;
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: returning "
+ ata_dev_printk(dev, KERN_DEBUG, "%s: returning "
"gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
__FUNCTION__, *gtf_length, *gtf_address, *obj_loc);
err = 0;
@@ -449,7 +447,7 @@ out:
/**
* taskfile_load_raw - send taskfile registers to host controller
- * @ap: Port to which output is sent
+ * @dev: target ATA device
* @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
*
* Outputs ATA taskfile to standard ATA host controller using MMIO
@@ -466,15 +464,15 @@ out:
* LOCKING: TBD:
* Inherited from caller.
*/
-static void taskfile_load_raw(struct ata_port *ap,
- struct ata_device *atadev,
- const struct taskfile_array *gtf)
+static void taskfile_load_raw(struct ata_device *dev,
+ const struct taskfile_array *gtf)
{
+ struct ata_port *ap = dev->ap;
struct ata_taskfile tf;
unsigned int err;
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
+ ata_dev_printk(dev, KERN_DEBUG, "%s: (0x1f1-1f7): hex: "
"%02x %02x %02x %02x %02x %02x %02x\n",
__FUNCTION__,
gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
@@ -485,7 +483,7 @@ static void taskfile_load_raw(struct ata_port *ap,
&& (gtf->tfa[6] == 0))
return;
- ata_tf_init(atadev, &tf);
+ ata_tf_init(dev, &tf);
/* convert gtf to tf */
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */
@@ -498,17 +496,16 @@ static void taskfile_load_raw(struct ata_port *ap,
tf.device = gtf->tfa[5]; /* 0x1f6 */
tf.command = gtf->tfa[6]; /* 0x1f7 */
- err = ata_exec_internal(atadev, &tf, NULL, DMA_NONE, NULL, 0);
+ err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err && ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_ERR,
+ ata_dev_printk(dev, KERN_ERR,
"%s: ata_exec_internal failed: %u\n",
__FUNCTION__, err);
}
/**
* do_drive_set_taskfiles - write the drive taskfile settings from _GTF
- * @ap: the ata_port for the drive
- * @atadev: target ata_device
+ * @dev: target ATA device
* @gtf_length: total number of bytes of _GTF taskfiles
* @gtf_address: location of _GTF taskfile arrays
*
@@ -517,30 +514,31 @@ static void taskfile_load_raw(struct ata_port *ap,
* Write {gtf_address, length gtf_length} in groups of
* REGS_PER_GTF bytes.
*/
-static int do_drive_set_taskfiles(struct ata_port *ap,
- struct ata_device *atadev, unsigned int gtf_length,
- unsigned long gtf_address)
+static int do_drive_set_taskfiles(struct ata_device *dev,
+ unsigned int gtf_length,
+ unsigned long gtf_address)
{
- int err = -ENODEV;
- int gtf_count = gtf_length / REGS_PER_GTF;
- int ix;
+ struct ata_port *ap = dev->ap;
+ int err = -ENODEV;
+ int gtf_count = gtf_length / REGS_PER_GTF;
+ int ix;
struct taskfile_array *gtf;
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
+ ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
__FUNCTION__, ap->port_no);
if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
return 0;
- if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
+ if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
goto out;
if (!gtf_count) /* shouldn't be here */
goto out;
if (gtf_length % REGS_PER_GTF) {
if (ata_msg_drv(ap))
- ata_dev_printk(atadev, KERN_ERR,
+ ata_dev_printk(dev, KERN_ERR,
"%s: unexpected GTF length (%d)\n",
__FUNCTION__, gtf_length);
goto out;
@@ -551,7 +549,7 @@ static int do_drive_set_taskfiles(struct ata_port *ap,
(gtf_address + ix * REGS_PER_GTF);
/* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
- taskfile_load_raw(ap, atadev, gtf);
+ taskfile_load_raw(dev, gtf);
}
err = 0;
@@ -567,11 +565,11 @@ out:
*/
int ata_acpi_exec_tfs(struct ata_port *ap)
{
- int ix;
- int ret =0;
- unsigned int gtf_length;
- unsigned long gtf_address;
- unsigned long obj_loc;
+ int ix;
+ int ret = 0;
+ unsigned int gtf_length;
+ unsigned long gtf_address;
+ unsigned long obj_loc;
if (libata_noacpi)
return 0;
@@ -584,11 +582,13 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
return 0;
for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
- if (!ata_dev_enabled(&ap->device[ix]))
+ struct ata_device *dev = &ap->device[ix];
+
+ if (!ata_dev_enabled(dev))
continue;
- ret = do_drive_get_GTF(ap, ix,
- &gtf_length, &gtf_address, &obj_loc);
+ ret = do_drive_get_GTF(dev, &gtf_length, &gtf_address,
+ &obj_loc);
if (ret < 0) {
if (ata_msg_probe(ap))
ata_port_printk(ap, KERN_DEBUG,
@@ -597,8 +597,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
break;
}
- ret = do_drive_set_taskfiles(ap, &ap->device[ix],
- gtf_length, gtf_address);
+ ret = do_drive_set_taskfiles(dev, gtf_length, gtf_address);
kfree((void *)obj_loc);
if (ret < 0) {
if (ata_msg_probe(ap))
@@ -614,8 +613,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
/**
* ata_acpi_push_id - send Identify data to drive
- * @ap: the ata_port for the drive
- * @ix: drive index
+ * @dev: target ATA device
*
* _SDD ACPI object: for SATA mode only
* Must be after Identify (Packet) Device -- uses its data
@@ -623,57 +621,57 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
* method and if it fails for whatever reason, we should still
* just keep going.
*/
-int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+int ata_acpi_push_id(struct ata_device *dev)
{
- acpi_handle handle;
- acpi_integer pcidevfn;
- int err;
- struct device *dev = ap->host->dev;
- struct ata_device *atadev = &ap->device[ix];
- u32 dev_adr;
- acpi_status status;
- struct acpi_object_list input;
- union acpi_object in_params[1];
+ struct ata_port *ap = dev->ap;
+ acpi_handle handle;
+ acpi_integer pcidevfn;
+ int err;
+ struct device *gdev = ap->host->dev;
+ u32 dev_adr;
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[1];
if (libata_noacpi)
return 0;
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
- __FUNCTION__, ix, ap->port_no);
+ ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n",
+ __FUNCTION__, dev->devno, ap->port_no);
/* Don't continue if not a SATA device. */
if (!(ap->cbl == ATA_CBL_SATA)) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: Not a SATA device\n", __FUNCTION__);
goto out;
}
/* Don't continue if device has no _ADR method.
* _SDD is intended for known motherboard devices. */
- err = sata_get_dev_handle(dev, &handle, &pcidevfn);
+ err = sata_get_dev_handle(gdev, &handle, &pcidevfn);
if (err < 0) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: sata_get_dev_handle failed (%d\n",
__FUNCTION__, err);
goto out;
}
/* Get this drive's _ADR info, if not already known */
- if (!atadev->obj_handle) {
+ if (!dev->obj_handle) {
dev_adr = SATA_ADR_RSVD;
- err = get_sata_adr(dev, handle, pcidevfn, ix, ap, atadev,
+ err = get_sata_adr(gdev, handle, pcidevfn, dev->devno, ap, dev,
&dev_adr);
if (err < 0 || dev_adr == SATA_ADR_RSVD ||
- !atadev->obj_handle) {
+ !dev->obj_handle) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s: get_sata_adr failed: "
"err=%d, dev_adr=%u, obj_handle=0x%p\n",
__FUNCTION__, err, dev_adr,
- atadev->obj_handle);
+ dev->obj_handle);
goto out;
}
}
@@ -683,19 +681,19 @@ int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
input.count = 1;
input.pointer = in_params;
in_params[0].type = ACPI_TYPE_BUFFER;
- in_params[0].buffer.length = sizeof(atadev->id[0]) * ATA_ID_WORDS;
- in_params[0].buffer.pointer = (u8 *)atadev->id;
+ in_params[0].buffer.length = sizeof(dev->id[0]) * ATA_ID_WORDS;
+ in_params[0].buffer.pointer = (u8 *)dev->id;
/* Output buffer: _SDD has no output */
/* It's OK for _SDD to be missing too. */
- swap_buf_le16(atadev->id, ATA_ID_WORDS);
- status = acpi_evaluate_object(atadev->obj_handle, "_SDD", &input, NULL);
- swap_buf_le16(atadev->id, ATA_ID_WORDS);
+ swap_buf_le16(dev->id, ATA_ID_WORDS);
+ status = acpi_evaluate_object(dev->obj_handle, "_SDD", &input, NULL);
+ swap_buf_le16(dev->id, ATA_ID_WORDS);
err = ACPI_FAILURE(status) ? -EIO : 0;
if (err < 0) {
if (ata_msg_probe(ap))
- ata_dev_printk(atadev, KERN_DEBUG,
+ ata_dev_printk(dev, KERN_DEBUG,
"%s _SDD error: status = 0x%x\n",
__FUNCTION__, status);
}
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 4595d1f8cf6..4166407eb47 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -101,6 +101,12 @@ int libata_noacpi = 1;
module_param_named(noacpi, libata_noacpi, int, 0444);
MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
+int ata_spindown_compat = 1;
+module_param_named(spindown_compat, ata_spindown_compat, int, 0644);
+MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown "
+ "behavior. Will be removed. More info can be found in "
+ "Documentation/feature-removal-schedule.txt\n");
+
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Library module for ATA devices");
MODULE_LICENSE("GPL");
@@ -1654,7 +1660,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
struct ata_taskfile tf;
unsigned int err_mask = 0;
const char *reason;
- int tried_spinup = 0;
+ int may_fallback = 1, tried_spinup = 0;
int rc;
if (ata_msg_ctl(ap))
@@ -1698,11 +1704,31 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
return -ENOENT;
}
+ /* Device or controller might have reported the wrong
+ * device class. Give a shot at the other IDENTIFY if
+ * the current one is aborted by the device.
+ */
+ if (may_fallback &&
+ (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+ may_fallback = 0;
+
+ if (class == ATA_DEV_ATA)
+ class = ATA_DEV_ATAPI;
+ else
+ class = ATA_DEV_ATA;
+ goto retry;
+ }
+
rc = -EIO;
reason = "I/O error";
goto err_out;
}
+ /* Falling back doesn't make sense if ID data was read
+ * successfully at least once.
+ */
+ may_fallback = 0;
+
swap_buf_le16(id, ATA_ID_WORDS);
/* sanity check */
@@ -1843,7 +1869,7 @@ int ata_dev_configure(struct ata_device *dev)
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
/* set _SDD */
- rc = ata_acpi_push_id(ap, dev->devno);
+ rc = ata_acpi_push_id(dev);
if (rc) {
ata_dev_printk(dev, KERN_WARNING, "failed to set _SDD(%d)\n",
rc);
@@ -2860,7 +2886,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
dev = &ap->device[i];
/* don't update suspended devices' xfer mode */
- if (!ata_dev_ready(dev))
+ if (!ata_dev_enabled(dev))
continue;
rc = ata_dev_set_mode(dev);
@@ -5845,37 +5871,11 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
*/
int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
{
- int i, j, rc;
+ int rc;
rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
- if (rc)
- goto fail;
-
- /* EH is quiescent now. Fail if we have any ready device.
- * This happens if hotplug occurs between completion of device
- * suspension and here.
- */
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- for (j = 0; j < ATA_MAX_DEVICES; j++) {
- struct ata_device *dev = &ap->device[j];
-
- if (ata_dev_ready(dev)) {
- ata_port_printk(ap, KERN_WARNING,
- "suspend failed, device %d "
- "still active\n", dev->devno);
- rc = -EBUSY;
- goto fail;
- }
- }
- }
-
- host->dev->power.power_state = mesg;
- return 0;
-
- fail:
- ata_host_resume(host);
+ if (rc == 0)
+ host->dev->power.power_state = mesg;
return rc;
}
@@ -5984,6 +5984,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
if (!ap)
return NULL;
+ ap->pflags |= ATA_PFLAG_INITIALIZING;
ap->lock = &host->lock;
ap->flags = ATA_FLAG_DISABLED;
ap->print_id = -1;
@@ -6352,6 +6353,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
ehi->action |= ATA_EH_SOFTRESET;
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
+ ap->pflags &= ~ATA_PFLAG_INITIALIZING;
ap->pflags |= ATA_PFLAG_LOADING;
ata_port_schedule_eh(ap);
@@ -6876,6 +6878,7 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
@@ -6889,11 +6892,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter);
EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
#endif /* CONFIG_PCI */
-#ifdef CONFIG_PM
-EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
-EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
-#endif /* CONFIG_PM */
-
EXPORT_SYMBOL_GPL(ata_eng_timeout);
EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
EXPORT_SYMBOL_GPL(ata_port_abort);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 8256655ce7d..5309c312f51 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -77,29 +77,12 @@ static void ata_eh_finish(struct ata_port *ap);
#ifdef CONFIG_PM
static void ata_eh_handle_port_suspend(struct ata_port *ap);
static void ata_eh_handle_port_resume(struct ata_port *ap);
-static int ata_eh_suspend(struct ata_port *ap,
- struct ata_device **r_failed_dev);
-static void ata_eh_prep_resume(struct ata_port *ap);
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev);
#else /* CONFIG_PM */
static void ata_eh_handle_port_suspend(struct ata_port *ap)
{ }
static void ata_eh_handle_port_resume(struct ata_port *ap)
{ }
-
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- return 0;
-}
-
-static void ata_eh_prep_resume(struct ata_port *ap)
-{ }
-
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- return 0;
-}
#endif /* CONFIG_PM */
static void ata_ering_record(struct ata_ering *ering, int is_io,
@@ -568,6 +551,9 @@ void ata_port_schedule_eh(struct ata_port *ap)
{
WARN_ON(!ap->ops->error_handler);
+ if (ap->pflags & ATA_PFLAG_INITIALIZING)
+ return;
+
ap->pflags |= ATA_PFLAG_EH_PENDING;
scsi_schedule_eh(ap->scsi_host);
@@ -1791,7 +1777,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
if (ehc->i.flags & ATA_EHI_DID_RESET)
readid_flags |= ATA_READID_POSTRESET;
- if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
+ if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
if (ata_port_offline(ap)) {
rc = -EIO;
goto err;
@@ -1872,166 +1858,6 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
return rc;
}
-#ifdef CONFIG_PM
-/**
- * ata_eh_suspend - handle suspend EH action
- * @ap: target host port
- * @r_failed_dev: result parameter to indicate failing device
- *
- * Handle suspend EH action. Disk devices are spinned down and
- * other types of devices are just marked suspended. Once
- * suspended, no EH action to the device is allowed until it is
- * resumed.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise
- */
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- struct ata_device *dev;
- int i, rc = 0;
-
- DPRINTK("ENTER\n");
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- unsigned long flags;
- unsigned int action, err_mask;
-
- dev = &ap->device[i];
- action = ata_eh_dev_action(dev);
-
- if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND))
- continue;
-
- WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED);
-
- ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND);
-
- if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
- /* flush cache */
- rc = ata_flush_cache(dev);
- if (rc)
- break;
-
- /* spin down */
- err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1);
- if (err_mask) {
- ata_dev_printk(dev, KERN_ERR, "failed to "
- "spin down (err_mask=0x%x)\n",
- err_mask);
- rc = -EIO;
- break;
- }
- }
-
- spin_lock_irqsave(ap->lock, flags);
- dev->flags |= ATA_DFLAG_SUSPENDED;
- spin_unlock_irqrestore(ap->lock, flags);
-
- ata_eh_done(ap, dev, ATA_EH_SUSPEND);
- }
-
- if (rc)
- *r_failed_dev = dev;
-
- DPRINTK("EXIT\n");
- return rc;
-}
-
-/**
- * ata_eh_prep_resume - prep for resume EH action
- * @ap: target host port
- *
- * Clear SUSPENDED in preparation for scheduled resume actions.
- * This allows other parts of EH to access the devices being
- * resumed.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- */
-static void ata_eh_prep_resume(struct ata_port *ap)
-{
- struct ata_device *dev;
- unsigned long flags;
- int i;
-
- DPRINTK("ENTER\n");
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- unsigned int action;
-
- dev = &ap->device[i];
- action = ata_eh_dev_action(dev);
-
- if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
- continue;
-
- spin_lock_irqsave(ap->lock, flags);
- dev->flags &= ~ATA_DFLAG_SUSPENDED;
- spin_unlock_irqrestore(ap->lock, flags);
- }
-
- DPRINTK("EXIT\n");
-}
-
-/**
- * ata_eh_resume - handle resume EH action
- * @ap: target host port
- * @r_failed_dev: result parameter to indicate failing device
- *
- * Handle resume EH action. Target devices are already reset and
- * revalidated. Spinning up is the only operation left.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise
- */
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
- struct ata_device *dev;
- int i, rc = 0;
-
- DPRINTK("ENTER\n");
-
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- unsigned int action, err_mask;
-
- dev = &ap->device[i];
- action = ata_eh_dev_action(dev);
-
- if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
- continue;
-
- ata_eh_about_to_do(ap, dev, ATA_EH_RESUME);
-
- if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
- err_mask = ata_do_simple_cmd(dev,
- ATA_CMD_IDLEIMMEDIATE);
- if (err_mask) {
- ata_dev_printk(dev, KERN_ERR, "failed to "
- "spin up (err_mask=0x%x)\n",
- err_mask);
- rc = -EIO;
- break;
- }
- }
-
- ata_eh_done(ap, dev, ATA_EH_RESUME);
- }
-
- if (rc)
- *r_failed_dev = dev;
-
- DPRINTK("EXIT\n");
- return 0;
-}
-#endif /* CONFIG_PM */
-
static int ata_port_nr_enabled(struct ata_port *ap)
{
int i, cnt = 0;
@@ -2057,17 +1883,6 @@ static int ata_eh_skip_recovery(struct ata_port *ap)
struct ata_eh_context *ehc = &ap->eh_context;
int i;
- /* skip if all possible devices are suspended */
- for (i = 0; i < ata_port_max_devices(ap); i++) {
- struct ata_device *dev = &ap->device[i];
-
- if (!(dev->flags & ATA_DFLAG_SUSPENDED))
- break;
- }
-
- if (i == ata_port_max_devices(ap))
- return 1;
-
/* thaw frozen port, resume link and recover failed devices */
if ((ap->pflags & ATA_PFLAG_FROZEN) ||
(ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
@@ -2147,9 +1962,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
if (ap->pflags & ATA_PFLAG_UNLOADING)
goto out;
- /* prep for resume */
- ata_eh_prep_resume(ap);
-
/* skip EH if possible. */
if (ata_eh_skip_recovery(ap))
ehc->i.action = 0;
@@ -2177,11 +1989,6 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
if (rc)
goto dev_fail;
- /* resume devices */
- rc = ata_eh_resume(ap, &dev);
- if (rc)
- goto dev_fail;
-
/* configure transfer mode if necessary */
if (ehc->i.flags & ATA_EHI_SETMODE) {
rc = ata_set_mode(ap, &dev);
@@ -2190,25 +1997,16 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
ehc->i.flags &= ~ATA_EHI_SETMODE;
}
- /* suspend devices */
- rc = ata_eh_suspend(ap, &dev);
- if (rc)
- goto dev_fail;
-
goto out;
dev_fail:
ehc->tries[dev->devno]--;
switch (rc) {
- case -EINVAL:
- /* eeek, something went very wrong, give up */
- ehc->tries[dev->devno] = 0;
- break;
-
case -ENODEV:
/* device missing or wrong IDENTIFY data, schedule probing */
ehc->i.probe_mask |= (1 << dev->devno);
+ case -EINVAL:
/* give it just one more chance */
ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
case -EIO:
@@ -2390,22 +2188,13 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)
*
* Resume @ap.
*
- * This function also waits upto one second until all devices
- * hanging off this port requests resume EH action. This is to
- * prevent invoking EH and thus reset multiple times on resume.
- *
- * On DPM resume, where some of devices might not be resumed
- * together, this may delay port resume upto one second, but such
- * DPM resumes are rare and 1 sec delay isn't too bad.
- *
* LOCKING:
* Kernel thread context (may sleep).
*/
static void ata_eh_handle_port_resume(struct ata_port *ap)
{
- unsigned long timeout;
unsigned long flags;
- int i, rc = 0;
+ int rc = 0;
/* are we resuming? */
spin_lock_irqsave(ap->lock, flags);
@@ -2416,31 +2205,12 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
}
spin_unlock_irqrestore(ap->lock, flags);
- /* spurious? */
- if (!(ap->pflags & ATA_PFLAG_SUSPENDED))
- goto done;
+ WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
if (ap->ops->port_resume)
rc = ap->ops->port_resume(ap);
- /* give devices time to request EH */
- timeout = jiffies + HZ; /* 1s max */
- while (1) {
- for (i = 0; i < ATA_MAX_DEVICES; i++) {
- struct ata_device *dev = &ap->device[i];
- unsigned int action = ata_eh_dev_action(dev);
-
- if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
- !(action & ATA_EH_RESUME))
- break;
- }
-
- if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout))
- break;
- msleep(10);
- }
-
- done:
+ /* report result */
spin_lock_irqsave(ap->lock, flags);
ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
if (ap->pm_result) {
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9afba2ba489..dd81fa78cdc 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -510,133 +510,6 @@ static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
}
}
-#ifdef CONFIG_PM
-/**
- * ata_scsi_device_suspend - suspend ATA device associated with sdev
- * @sdev: the SCSI device to suspend
- * @mesg: target power management message
- *
- * Request suspend EH action on the ATA device associated with
- * @sdev and wait for the operation to complete.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg)
-{
- struct ata_port *ap = ata_shost_to_port(sdev->host);
- struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
- unsigned long flags;
- unsigned int action;
- int rc = 0;
-
- if (!dev)
- goto out;
-
- spin_lock_irqsave(ap->lock, flags);
-
- /* wait for the previous resume to complete */
- while (dev->flags & ATA_DFLAG_SUSPENDED) {
- spin_unlock_irqrestore(ap->lock, flags);
- ata_port_wait_eh(ap);
- spin_lock_irqsave(ap->lock, flags);
- }
-
- /* if @sdev is already detached, nothing to do */
- if (sdev->sdev_state == SDEV_OFFLINE ||
- sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
- goto out_unlock;
-
- /* request suspend */
- action = ATA_EH_SUSPEND;
- if (mesg.event != PM_EVENT_SUSPEND)
- action |= ATA_EH_PM_FREEZE;
- ap->eh_info.dev_action[dev->devno] |= action;
- ap->eh_info.flags |= ATA_EHI_QUIET;
- ata_port_schedule_eh(ap);
-
- spin_unlock_irqrestore(ap->lock, flags);
-
- /* wait for EH to do the job */
- ata_port_wait_eh(ap);
-
- spin_lock_irqsave(ap->lock, flags);
-
- /* If @sdev is still attached but the associated ATA device
- * isn't suspended, the operation failed.
- */
- if (sdev->sdev_state != SDEV_OFFLINE &&
- sdev->sdev_state != SDEV_CANCEL && sdev->sdev_state != SDEV_DEL &&
- !(dev->flags & ATA_DFLAG_SUSPENDED))
- rc = -EIO;
-
- out_unlock:
- spin_unlock_irqrestore(ap->lock, flags);
- out:
- if (rc == 0)
- sdev->sdev_gendev.power.power_state = mesg;
- return rc;
-}
-
-/**
- * ata_scsi_device_resume - resume ATA device associated with sdev
- * @sdev: the SCSI device to resume
- *
- * Request resume EH action on the ATA device associated with
- * @sdev and return immediately. This enables parallel
- * wakeup/spinup of devices.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0.
- */
-int ata_scsi_device_resume(struct scsi_device *sdev)
-{
- struct ata_port *ap = ata_shost_to_port(sdev->host);
- struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
- struct ata_eh_info *ehi = &ap->eh_info;
- unsigned long flags;
- unsigned int action;
-
- if (!dev)
- goto out;
-
- spin_lock_irqsave(ap->lock, flags);
-
- /* if @sdev is already detached, nothing to do */
- if (sdev->sdev_state == SDEV_OFFLINE ||
- sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
- goto out_unlock;
-
- /* request resume */
- action = ATA_EH_RESUME;
- if (sdev->sdev_gendev.power.power_state.event == PM_EVENT_SUSPEND)
- __ata_ehi_hotplugged(ehi);
- else
- action |= ATA_EH_PM_FREEZE | ATA_EH_SOFTRESET;
- ehi->dev_action[dev->devno] |= action;
-
- /* We don't want autopsy and verbose EH messages. Disable
- * those if we're the only device on this link.
- */
- if (ata_port_max_devices(ap) == 1)
- ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
-
- ata_port_schedule_eh(ap);
-
- out_unlock:
- spin_unlock_irqrestore(ap->lock, flags);
- out:
- sdev->sdev_gendev.power.power_state = PMSG_ON;
- return 0;
-}
-#endif /* CONFIG_PM */
-
/**
* ata_to_sense_error - convert ATA error to SCSI error
* @id: ATA device number
@@ -929,6 +802,8 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
+ sdev->manage_start_stop = 1;
+
if (dev)
ata_scsi_dev_config(sdev, dev);
@@ -1069,9 +944,35 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
}
tf->command = ATA_CMD_VERIFY; /* READ VERIFY */
- } else
+ } else {
+ /* XXX: This is for backward compatibility, will be
+ * removed. Read Documentation/feature-removal-schedule.txt
+ * for more info.
+ */
+ if (ata_spindown_compat &&
+ (system_state == SYSTEM_HALT ||
+ system_state == SYSTEM_POWER_OFF)) {
+ static int warned = 0;
+
+ if (!warned) {
+ spin_unlock_irq(qc->ap->lock);
+ ata_dev_printk(qc->dev, KERN_WARNING,
+ "DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
+ "UPDATE SHUTDOWN UTILITY\n");
+ ata_dev_printk(qc->dev, KERN_WARNING,
+ "For more info, visit "
+ "http://linux-ata.org/shutdown.html\n");
+ warned = 1;
+ ssleep(5);
+ spin_lock_irq(qc->ap->lock);
+ }
+ scmd->result = SAM_STAT_GOOD;
+ return 1;
+ }
+
/* Issue ATA STANDBY IMMEDIATE command */
tf->command = ATA_CMD_STANDBYNOW1;
+ }
/*
* Standby and Idle condition timers could be implemented but that
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index d211db6b35a..e35d13466c6 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -544,7 +544,7 @@ static int ata_resources_present(struct pci_dev *pdev, int port)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-static int ata_pci_init_bmdma(struct ata_host *host)
+int ata_pci_init_bmdma(struct ata_host *host)
{
struct device *gdev = host->dev;
struct pci_dev *pdev = to_pci_dev(gdev);
@@ -566,7 +566,7 @@ static int ata_pci_init_bmdma(struct ata_host *host)
}
host->iomap = pcim_iomap_table(pdev);
- for (i = 0; i < host->n_ports; i++) {
+ for (i = 0; i < 2; i++) {
struct ata_port *ap = host->ports[i];
void __iomem *bmdma = host->iomap[4] + 8 * i;
@@ -585,54 +585,52 @@ static int ata_pci_init_bmdma(struct ata_host *host)
/**
* ata_pci_init_native_host - acquire native ATA resources and init host
* @host: target ATA host
- * @port_mask: ports to consider
*
- * Acquire native PCI ATA resources for @host and initialize
- * @host accordoingly.
+ * Acquire native PCI ATA resources for @host and initialize the
+ * first two ports of @host accordingly. Ports marked dummy are
+ * skipped and allocation failure makes the port dummy.
*
* LOCKING:
* Inherited from calling layer (may sleep).
*
* RETURNS:
- * 0 on success, -errno otherwise.
+ * 0 if at least one port is initialized, -ENODEV if no port is
+ * available.
*/
-int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
+int ata_pci_init_native_host(struct ata_host *host)
{
struct device *gdev = host->dev;
struct pci_dev *pdev = to_pci_dev(gdev);
+ unsigned int mask = 0;
int i, rc;
- /* Discard disabled ports. Some controllers show their unused
- * channels this way. Disabled ports are made dummy.
- */
- for (i = 0; i < 2; i++) {
- if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) {
- host->ports[i]->ops = &ata_dummy_port_ops;
- port_mask &= ~(1 << i);
- }
- }
-
- if (!port_mask) {
- dev_printk(KERN_ERR, gdev, "no available port\n");
- return -ENODEV;
- }
-
/* request, iomap BARs and init port addresses accordingly */
for (i = 0; i < 2; i++) {
struct ata_port *ap = host->ports[i];
int base = i * 2;
void __iomem * const *iomap;
- if (!(port_mask & (1 << i)))
+ if (ata_port_is_dummy(ap))
+ continue;
+
+ /* Discard disabled ports. Some controllers show
+ * their unused channels this way. Disabled ports are
+ * made dummy.
+ */
+ if (!ata_resources_present(pdev, i)) {
+ ap->ops = &ata_dummy_port_ops;
continue;
+ }
rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME);
if (rc) {
- dev_printk(KERN_ERR, gdev, "failed to request/iomap "
- "BARs for port %d (errno=%d)\n", i, rc);
+ dev_printk(KERN_WARNING, gdev,
+ "failed to request/iomap BARs for port %d "
+ "(errno=%d)\n", i, rc);
if (rc == -EBUSY)
pcim_pin_device(pdev);
- return rc;
+ ap->ops = &ata_dummy_port_ops;
+ continue;
}
host->iomap = iomap = pcim_iomap_table(pdev);
@@ -641,6 +639,13 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
ap->ioaddr.ctl_addr = (void __iomem *)
((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
ata_std_ports(&ap->ioaddr);
+
+ mask |= 1 << i;
+ }
+
+ if (!mask) {
+ dev_printk(KERN_ERR, gdev, "no available native port\n");
+ return -ENODEV;
}
return 0;
@@ -649,8 +654,7 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
/**
* ata_pci_prepare_native_host - helper to prepare native PCI ATA host
* @pdev: target PCI device
- * @ppi: array of port_info
- * @n_ports: number of ports to allocate
+ * @ppi: array of port_info, must be enough for two ports
* @r_host: out argument for the initialized ATA host
*
* Helper to allocate ATA host for @pdev, acquire all native PCI
@@ -664,10 +668,9 @@ int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
*/
int ata_pci_prepare_native_host(struct pci_dev *pdev,
const struct ata_port_info * const * ppi,
- int n_ports, struct ata_host **r_host)
+ struct ata_host **r_host)
{
struct ata_host *host;
- unsigned int port_mask;
int rc;
if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
@@ -681,11 +684,7 @@ int ata_pci_prepare_native_host(struct pci_dev *pdev,
goto err_out;
}
- port_mask = ATA_PORT_PRIMARY;
- if (n_ports > 1)
- port_mask |= ATA_PORT_SECONDARY;
-
- rc = ata_pci_init_native_host(host, port_mask);
+ rc = ata_pci_init_native_host(host);
if (rc)
goto err_out;
@@ -777,8 +776,11 @@ static int ata_init_legacy_port(struct ata_port *ap,
/* iomap cmd and ctl ports */
legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
- if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no])
+ if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no]) {
+ dev_printk(KERN_WARNING, host->dev,
+ "failed to map cmd/ctl ports\n");
return -ENOMEM;
+ }
/* init IO addresses */
ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
@@ -792,19 +794,20 @@ static int ata_init_legacy_port(struct ata_port *ap,
/**
* ata_init_legacy_host - acquire legacy ATA resources and init ATA host
* @host: target ATA host
- * @legacy_mask: out parameter, mask indicating ports is in legacy mode
* @was_busy: out parameter, indicates whether any port was busy
*
- * Acquire legacy ATA resources for ports.
+ * Acquire legacy ATA resources for the first two ports of @host
+ * and initialize it accordingly. Ports marked dummy are skipped
+ * and resource acquistion failure makes the port dummy.
*
* LOCKING:
* Inherited from calling layer (may sleep).
*
* RETURNS:
- * 0 on success, -errno otherwise.
+ * 0 if at least one port is initialized, -ENODEV if no port is
+ * available.
*/
-static int ata_init_legacy_host(struct ata_host *host,
- unsigned int *legacy_mask, int *was_busy)
+static int ata_init_legacy_host(struct ata_host *host, int *was_busy)
{
struct device *gdev = host->dev;
struct ata_legacy_devres *legacy_dr;
@@ -821,22 +824,23 @@ static int ata_init_legacy_host(struct ata_host *host,
devres_add(gdev, legacy_dr);
for (i = 0; i < 2; i++) {
- *legacy_mask &= ~(1 << i);
+ if (ata_port_is_dummy(host->ports[i]))
+ continue;
+
rc = ata_init_legacy_port(host->ports[i], legacy_dr);
if (rc == 0)
legacy_dr->mask |= 1 << i;
- else if (rc == -EBUSY)
- (*was_busy)++;
- }
-
- if (!legacy_dr->mask)
- return -EBUSY;
-
- for (i = 0; i < 2; i++)
- if (!(legacy_dr->mask & (1 << i)))
+ else {
+ if (rc == -EBUSY)
+ (*was_busy)++;
host->ports[i]->ops = &ata_dummy_port_ops;
+ }
+ }
- *legacy_mask |= legacy_dr->mask;
+ if (!legacy_dr->mask) {
+ dev_printk(KERN_ERR, gdev, "no available legacy port\n");
+ return -ENODEV;
+ }
devres_remove_group(gdev, NULL);
return 0;
@@ -875,7 +879,7 @@ static int ata_request_legacy_irqs(struct ata_host *host,
legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
BUG_ON(!legacy_dr);
- for (i = 0; i < host->n_ports; i++) {
+ for (i = 0; i < 2; i++) {
unsigned int irq;
/* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
@@ -923,8 +927,7 @@ static int ata_request_legacy_irqs(struct ata_host *host,
/**
* ata_pci_init_one - Initialize/register PCI IDE host controller
* @pdev: Controller to be initialized
- * @port_info: Information from low-level host driver
- * @n_ports: Number of ports attached to host controller
+ * @ppi: array of port_info, must be enough for two ports
*
* This is a helper function which can be called from a driver's
* xxx_init_one() probe function if the hardware uses traditional
@@ -944,26 +947,34 @@ static int ata_request_legacy_irqs(struct ata_host *host,
* RETURNS:
* Zero on success, negative on errno-based value on error.
*/
-
-int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
- unsigned int n_ports)
+int ata_pci_init_one(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi)
{
struct device *dev = &pdev->dev;
+ const struct ata_port_info *pi = NULL;
struct ata_host *host = NULL;
- const struct ata_port_info *port[2];
u8 mask;
- unsigned int legacy_mode = 0;
- int rc;
+ int legacy_mode = 0;
+ int i, rc;
DPRINTK("ENTER\n");
- if (!devres_open_group(dev, NULL, GFP_KERNEL))
- return -ENOMEM;
+ /* look up the first valid port_info */
+ for (i = 0; i < 2 && ppi[i]; i++) {
+ if (ppi[i]->port_ops != &ata_dummy_port_ops) {
+ pi = ppi[i];
+ break;
+ }
+ }
- BUG_ON(n_ports < 1 || n_ports > 2);
+ if (!pi) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "no valid port_info specified\n");
+ return -EINVAL;
+ }
- port[0] = port_info[0];
- port[1] = (n_ports > 1) ? port_info[1] : NULL;
+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
/* FIXME: Really for ATA it isn't safe because the device may be
multi-purpose and we want to leave it alone if it was already
@@ -984,7 +995,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
mask = (1 << 2) | (1 << 0);
if ((tmp8 & mask) != mask)
- legacy_mode = (1 << 3);
+ legacy_mode = 1;
#if defined(CONFIG_NO_ATA_LEGACY)
/* Some platforms with PCI limits cannot address compat
port space. In that case we punt if their firmware has
@@ -998,7 +1009,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
/* alloc and init host */
- host = ata_host_alloc_pinfo(dev, port, n_ports);
+ host = ata_host_alloc_pinfo(dev, ppi, 2);
if (!host) {
dev_printk(KERN_ERR, &pdev->dev,
"failed to allocate ATA host\n");
@@ -1007,19 +1018,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
if (!legacy_mode) {
- unsigned int port_mask;
-
- port_mask = ATA_PORT_PRIMARY;
- if (n_ports > 1)
- port_mask |= ATA_PORT_SECONDARY;
-
- rc = ata_pci_init_native_host(host, port_mask);
+ rc = ata_pci_init_native_host(host);
if (rc)
goto err_out;
} else {
int was_busy = 0;
- rc = ata_init_legacy_host(host, &legacy_mode, &was_busy);
+ rc = ata_init_legacy_host(host, &was_busy);
if (was_busy)
pcim_pin_device(pdev);
if (rc)
@@ -1040,8 +1045,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out;
if (!legacy_mode)
- rc = devm_request_irq(dev, pdev->irq,
- port_info[0]->port_ops->irq_handler,
+ rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler,
IRQF_SHARED, DRV_NAME, host);
else {
irq_handler_t handler[2] = { host->ops->irq_handler,
@@ -1055,7 +1059,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
goto err_out;
/* register */
- rc = ata_host_register(host, port_info[0]->sht);
+ rc = ata_host_register(host, pi->sht);
if (rc)
goto err_out;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 5f4d40cd328..8b71b73a199 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -58,6 +58,7 @@ extern int atapi_enabled;
extern int atapi_dmadir;
extern int libata_fua;
extern int libata_noacpi;
+extern int ata_spindown_compat;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
@@ -96,15 +97,15 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
extern struct ata_port *ata_port_alloc(struct ata_host *host);
/* libata-acpi.c */
-#ifdef CONFIG_SATA_ACPI
+#ifdef CONFIG_ATA_ACPI
extern int ata_acpi_exec_tfs(struct ata_port *ap);
-extern int ata_acpi_push_id(struct ata_port *ap, unsigned int ix);
+extern int ata_acpi_push_id(struct ata_device *dev);
#else
static inline int ata_acpi_exec_tfs(struct ata_port *ap)
{
return 0;
}
-static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
+static inline int ata_acpi_push_id(struct ata_device *dev)
{
return 0;
}
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index d40edebb510..3c55a5ff74c 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -291,10 +291,6 @@ static struct scsi_host_template ali_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
/*
@@ -522,14 +518,14 @@ static void ali_init_chipset(struct pci_dev *pdev)
static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info_early = {
+ static const struct ata_port_info info_early = {
.sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.port_ops = &ali_early_port_ops
};
/* Revision 0x20 added DMA */
- static struct ata_port_info info_20 = {
+ static const struct ata_port_info info_20 = {
.sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
@@ -537,7 +533,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &ali_20_port_ops
};
/* Revision 0x20 with support logic added UDMA */
- static struct ata_port_info info_20_udma = {
+ static const struct ata_port_info info_20_udma = {
.sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
@@ -546,7 +542,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &ali_20_port_ops
};
/* Revision 0xC2 adds UDMA66 */
- static struct ata_port_info info_c2 = {
+ static const struct ata_port_info info_c2 = {
.sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
@@ -555,7 +551,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC3 is UDMA100 */
- static struct ata_port_info info_c3 = {
+ static const struct ata_port_info info_c3 = {
.sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
@@ -564,7 +560,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC4 is UDMA133 */
- static struct ata_port_info info_c4 = {
+ static const struct ata_port_info info_c4 = {
.sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
@@ -573,7 +569,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC5 is UDMA133 with LBA48 DMA */
- static struct ata_port_info info_c5 = {
+ static const struct ata_port_info info_c5 = {
.sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -582,7 +578,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &ali_c5_port_ops
};
- static struct ata_port_info *port_info[2];
+ const struct ata_port_info *ppi[] = { NULL, NULL };
u8 rev, tmp;
struct pci_dev *isa_bridge;
@@ -594,17 +590,17 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
*/
if (rev < 0x20) {
- port_info[0] = port_info[1] = &info_early;
+ ppi[0] = &info_early;
} else if (rev < 0xC2) {
- port_info[0] = port_info[1] = &info_20;
+ ppi[0] = &info_20;
} else if (rev == 0xC2) {
- port_info[0] = port_info[1] = &info_c2;
+ ppi[0] = &info_c2;
} else if (rev == 0xC3) {
- port_info[0] = port_info[1] = &info_c3;
+ ppi[0] = &info_c3;
} else if (rev == 0xC4) {
- port_info[0] = port_info[1] = &info_c4;
+ ppi[0] = &info_c4;
} else
- port_info[0] = port_info[1] = &info_c5;
+ ppi[0] = &info_c5;
ali_init_chipset(pdev);
@@ -613,10 +609,10 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Are we paired with a UDMA capable chip */
pci_read_config_byte(isa_bridge, 0x5E, &tmp);
if ((tmp & 0x1E) == 0x12)
- port_info[0] = port_info[1] = &info_20_udma;
+ ppi[0] = &info_20_udma;
pci_dev_put(isa_bridge);
}
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 67c7e87dec0..b439351f1fd 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -324,10 +324,6 @@ static struct scsi_host_template amd_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations amd33_port_ops = {
@@ -542,7 +538,7 @@ static struct ata_port_operations nv133_port_ops = {
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info[10] = {
+ static const struct ata_port_info info[10] = {
{ /* 0: AMD 7401 */
.sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -624,7 +620,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd100_port_ops
}
};
- static struct ata_port_info *port_info[2];
+ const struct ata_port_info *ppi[] = { NULL, NULL };
static int printed_version;
int type = id->driver_data;
u8 rev;
@@ -656,9 +652,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
ata_pci_clear_simplex(pdev);
/* And fire it up */
-
- port_info[0] = port_info[1] = &info[type];
- return ata_pci_init_one(pdev, port_info, 2);
+ ppi[0] = &info[type];
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index ef51940c3ad..9861059dd67 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -414,7 +414,7 @@ static const struct ata_port_operations artop6260_ops = {
static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
static int printed_version;
- static struct ata_port_info info_6210 = {
+ static const struct ata_port_info info_6210 = {
.sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -422,7 +422,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA2,
.port_ops = &artop6210_ops,
};
- static struct ata_port_info info_626x = {
+ static const struct ata_port_info info_626x = {
.sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -430,7 +430,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA4,
.port_ops = &artop6260_ops,
};
- static struct ata_port_info info_626x_fast = {
+ static const struct ata_port_info info_626x_fast = {
.sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -438,32 +438,30 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA5,
.port_ops = &artop6260_ops,
};
- struct ata_port_info *port_info[2];
- struct ata_port_info *info = NULL;
- int ports = 2;
+ const struct ata_port_info *ppi[] = { NULL, NULL };
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
if (id->driver_data == 0) { /* 6210 variant */
- info = &info_6210;
+ ppi[0] = &info_6210;
+ ppi[1] = &ata_dummy_port_info;
/* BIOS may have left us in UDMA, clear it before libata probe */
pci_write_config_byte(pdev, 0x54, 0);
/* For the moment (also lacks dsc) */
printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n");
printk(KERN_WARNING "Secondary ATA ports will not be activated.\n");
- ports = 1;
}
else if (id->driver_data == 1) /* 6260 */
- info = &info_626x;
+ ppi[0] = &info_626x;
else if (id->driver_data == 2) { /* 6260 or 6260 + fast */
unsigned long io = pci_resource_start(pdev, 4);
u8 reg;
- info = &info_626x;
+ ppi[0] = &info_626x;
if (inb(io) & 0x10)
- info = &info_626x_fast;
+ ppi[0] = &info_626x_fast;
/* Mac systems come up with some registers not set as we
will need them */
@@ -484,10 +482,9 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
}
- BUG_ON(info == NULL);
+ BUG_ON(ppi[0] == NULL);
- port_info[0] = port_info[1] = info;
- return ata_pci_init_one(pdev, port_info, ports);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id artop_pci_tbl[] = {
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 21515381b5b..844914681a2 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -229,10 +229,6 @@ static struct scsi_host_template atiixp_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations atiixp_port_ops = {
@@ -272,7 +268,7 @@ static struct ata_port_operations atiixp_port_ops = {
static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &atiixp_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -280,8 +276,8 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x3F,
.port_ops = &atiixp_port_ops
};
- static struct ata_port_info *port_info[2] = { &info, &info };
- return ata_pci_init_one(dev, port_info, 2);
+ const struct ata_port_info *ppi[] = { &info, NULL };
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id atiixp[] = {
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 2105985a801..ed00fa9d53b 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -181,10 +181,6 @@ static struct scsi_host_template cmd640_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cmd640_port_ops = {
@@ -253,17 +249,16 @@ static void cmd640_hardware_init(struct pci_dev *pdev)
static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &cmd640_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.port_ops = &cmd640_port_ops
};
-
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
cmd640_hardware_init(pdev);
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
static int cmd640_reinit_one(struct pci_dev *pdev)
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 3989cc577fc..2a79b335cfc 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -266,10 +266,6 @@ static struct scsi_host_template cmd64x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cmd64x_port_ops = {
@@ -381,7 +377,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
u32 class_rev;
- static struct ata_port_info cmd_info[6] = {
+ static const struct ata_port_info cmd_info[6] = {
{ /* CMD 643 - no UDMA */
.sht = &cmd64x_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -428,11 +424,9 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &cmd648_port_ops
}
};
- static struct ata_port_info *port_info[2], *info;
+ const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
u8 mrdmode;
- info = &cmd_info[id->driver_data];
-
pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
@@ -442,10 +436,10 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (pdev->device == PCI_DEVICE_ID_CMD_646) {
/* Does UDMA work ? */
if (class_rev > 4)
- info = &cmd_info[2];
+ ppi[0] = &cmd_info[2];
/* Early rev with other problems ? */
else if (class_rev == 1)
- info = &cmd_info[3];
+ ppi[0] = &cmd_info[3];
}
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
@@ -461,8 +455,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
#endif
- port_info[0] = port_info[1] = info;
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 79bef0d1fad..83bcc5b3259 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -155,10 +155,6 @@ static struct scsi_host_template cs5520_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cs5520_port_ops = {
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 29642d5ee18..1b67923d7a4 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -176,10 +176,6 @@ static struct scsi_host_template cs5530_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cs5530_port_ops = {
@@ -339,7 +335,7 @@ fail_put:
static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &cs5530_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -348,23 +344,23 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &cs5530_port_ops
};
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
- static struct ata_port_info info_palmax_secondary = {
+ static const struct ata_port_info info_palmax_secondary = {
.sht = &cs5530_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
.port_ops = &cs5530_port_ops
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
/* Chip initialisation */
if (cs5530_init_chip())
return -ENODEV;
if (cs5530_is_palmax())
- port_info[1] = &info_palmax_secondary;
+ ppi[1] = &info_palmax_secondary;
/* Now kick off ATA set up */
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 22006ae7194..f37d4cd812a 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -173,10 +173,6 @@ static struct scsi_host_template cs5535_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cs5535_port_ops = {
@@ -227,7 +223,7 @@ static struct ata_port_operations cs5535_port_ops = {
static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &cs5535_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -235,7 +231,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x1f,
.port_ops = &cs5535_port_ops
};
- struct ata_port_info *ports[1] = { &info };
+ const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
u32 timings, dummy;
@@ -247,7 +243,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
rdmsr(ATAC_CH0D1_PIO, timings, dummy);
if (CS5535_BAD_PIO(timings))
wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0);
- return ata_pci_init_one(dev, ports, 1);
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id cs5535[] = {
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index 6ec049c3b1d..27b9f29c01e 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -125,10 +125,6 @@ static struct scsi_host_template cy82c693_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations cy82c693_port_ops = {
@@ -169,14 +165,14 @@ static struct ata_port_operations cy82c693_port_ops = {
static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &cy82c693_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cy82c693_port_ops
};
- static struct ata_port_info *port_info[1] = { &info };
+ const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
/* Devfn 1 is the ATA primary. The secondary is magic and on devfn2.
For the moment we don't handle the secondary. FIXME */
@@ -184,7 +180,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
if (PCI_FUNC(pdev->devfn) != 1)
return -ENODEV;
- return ata_pci_init_one(pdev, port_info, 1);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id cy82c693[] = {
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index d0f52e03490..079248a9b46 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -247,10 +247,6 @@ static struct scsi_host_template efar_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations efar_ops = {
@@ -305,7 +301,7 @@ static const struct ata_port_operations efar_ops = {
static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &efar_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -313,13 +309,13 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
.udma_mask = 0x0f, /* UDMA 66 */
.port_ops = &efar_ops,
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id efar_pci_tbl[] = {
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index e64e05e5c7f..c6c8a8bb06d 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -331,10 +331,6 @@ static struct scsi_host_template hpt36x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
/*
@@ -421,7 +417,7 @@ static void hpt36x_init_chipset(struct pci_dev *dev)
static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info_hpt366 = {
+ static const struct ata_port_info info_hpt366 = {
.sht = &hpt36x_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -429,7 +425,8 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x1f,
.port_ops = &hpt366_port_ops
};
- struct ata_port_info *port_info[2] = {&info_hpt366, &info_hpt366};
+ struct ata_port_info info = info_hpt366;
+ const struct ata_port_info *ppi[] = { &info, NULL };
u32 class_rev;
u32 reg1;
@@ -450,17 +447,17 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* info_hpt366 is safe against re-entry so we can scribble on it */
switch((reg1 & 0x700) >> 8) {
case 5:
- info_hpt366.private_data = &hpt366_40;
+ info.private_data = &hpt366_40;
break;
case 9:
- info_hpt366.private_data = &hpt366_25;
+ info.private_data = &hpt366_25;
break;
default:
- info_hpt366.private_data = &hpt366_33;
+ info.private_data = &hpt366_33;
break;
}
/* Now kick off ATA set up */
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 1614e8c822a..5a0a410654e 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -887,7 +887,7 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev)
static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* HPT370 - UDMA100 */
- static struct ata_port_info info_hpt370 = {
+ static const struct ata_port_info info_hpt370 = {
.sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -896,7 +896,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
- static struct ata_port_info info_hpt370a = {
+ static const struct ata_port_info info_hpt370a = {
.sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -905,7 +905,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &hpt370a_port_ops
};
/* HPT370 - UDMA100 */
- static struct ata_port_info info_hpt370_33 = {
+ static const struct ata_port_info info_hpt370_33 = {
.sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -914,7 +914,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
- static struct ata_port_info info_hpt370a_33 = {
+ static const struct ata_port_info info_hpt370a_33 = {
.sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -923,7 +923,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &hpt370a_port_ops
};
/* HPT371, 372 and friends - UDMA133 */
- static struct ata_port_info info_hpt372 = {
+ static const struct ata_port_info info_hpt372 = {
.sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -932,7 +932,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &hpt372_port_ops
};
/* HPT371, 372 and friends - UDMA100 at 50MHz clock */
- static struct ata_port_info info_hpt372_50 = {
+ static const struct ata_port_info info_hpt372_50 = {
.sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -941,7 +941,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &hpt372_port_ops
};
/* HPT374 - UDMA133 */
- static struct ata_port_info info_hpt374 = {
+ static const struct ata_port_info info_hpt374 = {
.sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -951,9 +951,10 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
};
static const int MHz[4] = { 33, 40, 50, 66 };
-
- struct ata_port_info *port_info[2];
- struct ata_port_info *port;
+ const struct ata_port_info *port;
+ void *private_data = NULL;
+ struct ata_port_info port_info;
+ const struct ata_port_info *ppi[] = { &port_info, NULL };
u8 irqmask;
u32 class_rev;
@@ -1124,13 +1125,13 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
}
if (clock_slot == 3)
- port->private_data = (void *)hpt37x_timings_66;
+ private_data = (void *)hpt37x_timings_66;
else
- port->private_data = (void *)hpt37x_timings_50;
+ private_data = (void *)hpt37x_timings_50;
printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
} else {
- port->private_data = (void *)chip_table->clocks[clock_slot];
+ private_data = (void *)chip_table->clocks[clock_slot];
/*
* Perform a final fixup. Note that we will have used the
* DPLL on the HPT372 which means we don't have to worry
@@ -1144,9 +1145,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
}
- port_info[0] = port_info[1] = port;
/* Now kick off ATA set up */
- return ata_pci_init_one(dev, port_info, 2);
+ port_info = *port;
+ port_info.private_data = private_data;
+
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id hpt37x[] = {
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index ea1037d6786..f25154aed75 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -488,7 +488,7 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* HPT372N and friends - UDMA133 */
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &hpt3x2n_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -496,8 +496,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x7f,
.port_ops = &hpt3x2n_port_ops
};
- struct ata_port_info *port_info[2];
- struct ata_port_info *port = &info;
+ struct ata_port_info port = info;
+ const struct ata_port_info *ppi[] = { &port, NULL };
u8 irqmask;
u32 class_rev;
@@ -585,9 +585,9 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* Set our private data up. We only need a few flags so we use
it directly */
- port->private_data = NULL;
+ port.private_data = NULL;
if (pci_mhz > 60) {
- port->private_data = (void *)PCI66;
+ port.private_data = (void *)PCI66;
/*
* On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
* the MISC. register to stretch the UltraDMA Tss timing.
@@ -598,8 +598,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
}
/* Now kick off ATA set up */
- port_info[0] = port_info[1] = port;
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id hpt3x2n[] = {
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index ac28ec8c50a..bbabe7902fb 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -100,10 +100,6 @@ static struct scsi_host_template hpt3x3_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations hpt3x3_port_ops = {
@@ -175,7 +171,7 @@ static void hpt3x3_init_chipset(struct pci_dev *dev)
static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &hpt3x3_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -183,11 +179,11 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x07,
.port_ops = &hpt3x3_port_ops
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
hpt3x3_init_chipset(dev);
/* Now kick off ATA set up */
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index 17bf9f3ed01..a769952646e 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -257,10 +257,6 @@ static struct scsi_host_template it8213_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations it8213_ops = {
@@ -315,7 +311,7 @@ static const struct ata_port_operations it8213_ops = {
static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &it8213_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -323,14 +319,14 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
.udma_mask = 0x1f, /* UDMA 100 */
.port_ops = &it8213_ops,
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ /* Current IT8213 stuff is single port */
+ const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- /* Current IT8213 stuff is single port */
- return ata_pci_init_one(pdev, port_info, 1);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id it8213_pci_tbl[] = {
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index f1f8cec8c22..ff9a6fd3665 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -620,10 +620,6 @@ static struct scsi_host_template it821x_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations it821x_smart_port_ops = {
@@ -722,14 +718,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
u8 conf;
- static struct ata_port_info info_smart = {
+ static const struct ata_port_info info_smart = {
.sht = &it821x_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &it821x_smart_port_ops
};
- static struct ata_port_info info_passthru = {
+ static const struct ata_port_info info_passthru = {
.sht = &it821x_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -737,8 +733,8 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = 0x7f,
.port_ops = &it821x_passthru_port_ops
};
- static struct ata_port_info *port_info[2];
+ const struct ata_port_info *ppi[] = { NULL, NULL };
static char *mode[2] = { "pass through", "smart" };
/* Force the card into bypass mode if so requested */
@@ -751,11 +747,11 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
printk(KERN_INFO DRV_NAME ": controller in %s mode.\n", mode[conf]);
if (conf == 0)
- port_info[0] = port_info[1] = &info_passthru;
+ ppi[0] = &info_passthru;
else
- port_info[0] = port_info[1] = &info_smart;
+ ppi[0] = &info_smart;
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 420c343e571..b994351fbcd 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -31,7 +31,7 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_ready(dev)) {
+ if (ata_dev_enabled(dev)) {
ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 1daf78ac6ef..8d799e87f75 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -138,10 +138,6 @@ static struct scsi_host_template jmicron_sht = {
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations jmicron_ops = {
@@ -195,7 +191,7 @@ static const struct ata_port_operations jmicron_ops = {
static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &jmicron_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -205,9 +201,9 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
.port_ops = &jmicron_ops,
};
- struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id jmicron_pci_tbl[] = {
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 837b7fe77dc..edbfe0dbbf7 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -107,10 +107,6 @@ static struct scsi_host_template marvell_sht = {
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations marvell_ops = {
@@ -165,7 +161,7 @@ static const struct ata_port_operations marvell_ops = {
static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &marvell_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -175,7 +171,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
.port_ops = &marvell_ops,
};
- static struct ata_port_info info_sata = {
+ static const struct ata_port_info info_sata = {
.sht = &marvell_sht,
/* Slave possible as its magically mapped not real */
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -186,13 +182,12 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
.port_ops = &marvell_ops,
};
- struct ata_port_info *port_info[2] = { &info, &info_sata };
- int n_port = 2;
+ const struct ata_port_info *ppi[] = { &info, &info_sata };
if (pdev->device == 0x6101)
- n_port = 1;
+ ppi[1] = &ata_dummy_port_info;
- return ata_pci_init_one(pdev, port_info, n_port);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id marvell_pci_tbl[] = {
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 9587a89f968..368fac7d168 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -280,10 +280,6 @@ static struct scsi_host_template mpc52xx_ata_sht = {
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static struct ata_port_operations mpc52xx_ata_port_ops = {
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 3bfbd495f64..4ea42838297 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -165,10 +165,6 @@ static struct scsi_host_template mpiix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations mpiix_port_ops = {
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index dbba5b77d79..81f56345866 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -37,10 +37,6 @@ static struct scsi_host_template netcell_sht = {
.slave_destroy = ata_scsi_slave_destroy,
/* Use standard CHS mapping rules */
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations netcell_ops = {
@@ -96,7 +92,7 @@ static const struct ata_port_operations netcell_ops = {
static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &netcell_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
/* Actually we don't really care about these as the
@@ -106,7 +102,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
.udma_mask = 0x3f, /* UDMA 133 */
.port_ops = &netcell_ops,
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *port_info[] = { &info, NULL };
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
@@ -116,7 +112,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
ata_pci_clear_simplex(pdev);
/* And let the library code do the work */
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, port_info);
}
static const struct pci_device_id netcell_pci_tbl[] = {
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index ebc58a907d2..ea70ec74487 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -158,10 +158,6 @@ static struct scsi_host_template ns87410_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations ns87410_port_ops = {
@@ -195,14 +191,14 @@ static struct ata_port_operations ns87410_port_ops = {
static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &ns87410_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x0F,
.port_ops = &ns87410_port_ops
};
- static struct ata_port_info *port_info[2] = {&info, &info};
- return ata_pci_init_one(dev, port_info, 2);
+ const struct ata_port_info *ppi[] = { &info, NULL };
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id ns87410[] = {
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 4d75d32e582..29c23ddd655 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -234,10 +234,6 @@ static struct scsi_host_template oldpiix_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations oldpiix_pata_ops = {
@@ -293,20 +289,20 @@ static const struct ata_port_operations oldpiix_pata_ops = {
static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &oldpiix_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
.port_ops = &oldpiix_pata_ops,
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id oldpiix_pci_tbl[] = {
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index 0af8a2c77cc..1c44653e1e0 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -179,10 +179,6 @@ static struct scsi_host_template opti_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations opti_port_ops = {
@@ -220,19 +216,19 @@ static struct ata_port_operations opti_port_ops = {
static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &opti_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.port_ops = &opti_port_ops
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
static int printed_version;
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id opti[] = {
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 2843e480f21..3093b02286c 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -363,10 +363,6 @@ static struct scsi_host_template optidma_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations optidma_port_ops = {
@@ -486,14 +482,14 @@ done_nomsg: /* Wrong chip revision */
static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info_82c700 = {
+ static const struct ata_port_info info_82c700 = {
.sht = &optidma_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &optidma_port_ops
};
- static struct ata_port_info info_82c700_udma = {
+ static const struct ata_port_info info_82c700_udma = {
.sht = &optidma_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -501,8 +497,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x07,
.port_ops = &optiplus_port_ops
};
- static struct ata_port_info *port_info[2];
- struct ata_port_info *info = &info_82c700;
+ const struct ata_port_info *ppi[] = { &info_82c700, NULL };
static int printed_version;
if (!printed_version++)
@@ -514,10 +509,9 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
pci_clock = inb(0x1F5) & 1; /* 0 = 33Mhz, 1 = 25Mhz */
if (optiplus_with_udma(dev))
- info = &info_82c700_udma;
+ ppi[0] = &info_82c700_udma;
- port_info[0] = port_info[1] = info;
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id optidma[] = {
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 11245e331f7..4d44c7555db 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -397,6 +397,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index ee636beb05e..edbaf9d653b 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -244,10 +244,6 @@ static struct scsi_host_template pdc202xx_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations pdc2024x_port_ops = {
@@ -321,7 +317,7 @@ static struct ata_port_operations pdc2026x_port_ops = {
static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info[3] = {
+ static const struct ata_port_info info[3] = {
{
.sht = &pdc202xx_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -348,9 +344,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
}
};
- static struct ata_port_info *port_info[2];
-
- port_info[0] = port_info[1] = &info[id->driver_data];
+ const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
if (dev->device == PCI_DEVICE_ID_PROMISE_20265) {
struct pci_dev *bridge = dev->bus->self;
@@ -362,7 +356,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
return -ENODEV;
}
}
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id pdc202xx[] = {
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index a0a650c7f27..1f6384895a4 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -48,6 +48,8 @@ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unuse
return 0;
}
+static int ata_dummy_ret0(struct ata_port *ap) { return 0; }
+
static struct scsi_host_template pata_platform_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -91,7 +93,7 @@ static struct ata_port_operations pata_platform_port_ops = {
.irq_on = ata_irq_on,
.irq_ack = ata_irq_ack,
- .port_start = ata_port_start,
+ .port_start = ata_dummy_ret0,
};
static void pata_platform_setup_port(struct ata_ioports *ioaddr,
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 1c54673e008..ba96b54f5b8 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -200,10 +200,6 @@ static struct scsi_host_template radisys_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations radisys_pata_ops = {
@@ -259,7 +255,7 @@ static const struct ata_port_operations radisys_pata_ops = {
static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &radisys_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -267,13 +263,13 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
.udma_mask = 0x14, /* UDMA33/66 only */
.port_ops = &radisys_pata_ops,
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id radisys_pci_tbl[] = {
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 85c45290eee..2bfd7ef42af 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -40,7 +40,7 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_ready(dev)) {
+ if (ata_dev_enabled(dev)) {
/* We don't really care */
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
@@ -69,10 +69,6 @@ static struct scsi_host_template rz1000_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations rz1000_port_ops = {
@@ -135,22 +131,20 @@ static int rz1000_fifo_disable(struct pci_dev *pdev)
static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_port_info *port_info[2];
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &rz1000_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.port_ops = &rz1000_port_ops
};
+ const struct ata_port_info *ppi[] = { &info, NULL };
if (!printed_version++)
printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
- if (rz1000_fifo_disable(pdev) == 0) {
- port_info[0] = &info;
- port_info[1] = &info;
- return ata_pci_init_one(pdev, port_info, 2);
- }
+ if (rz1000_fifo_disable(pdev) == 0)
+ return ata_pci_init_one(pdev, ppi);
+
printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n");
/* Not safe to use so skip */
return -ENODEV;
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 66e8ff467c8..225013ecf4b 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -194,10 +194,6 @@ static struct scsi_host_template sc1200_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations sc1200_port_ops = {
@@ -247,7 +243,7 @@ static struct ata_port_operations sc1200_port_ops = {
static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &sc1200_sht,
.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -255,10 +251,10 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = 0x07,
.port_ops = &sc1200_port_ops
};
- static struct ata_port_info *port_info[2] = { &info, &info };
-
/* Can't enable port 2 yet, see top comments */
- return ata_pci_init_one(dev, port_info, 1);
+ const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
+
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id sc1200[] = {
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 203f463ac39..cca3aa225ef 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -984,10 +984,6 @@ static struct scsi_host_template scc_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations scc_pata_ops = {
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index b6e020383dd..dee6e211949 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -315,10 +315,6 @@ static struct scsi_host_template serverworks_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations serverworks_osb4_port_ops = {
@@ -479,8 +475,7 @@ static void serverworks_fixup_ht1000(struct pci_dev *pdev)
static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- int ports = 2;
- static struct ata_port_info info[4] = {
+ static const struct ata_port_info info[4] = {
{ /* OSB4 */
.sht = &serverworks_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -511,8 +506,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
.port_ops = &serverworks_csb_port_ops
}
};
- static struct ata_port_info *port_info[2];
- struct ata_port_info *devinfo = &info[id->driver_data];
+ const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
/* Force master latency timer to 64 PCI clocks */
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
@@ -521,7 +515,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
/* Select non UDMA capable OSB4 if we can't do fixups */
if ( serverworks_fixup_osb4(pdev) < 0)
- devinfo = &info[1];
+ ppi[0] = &info[1];
}
/* setup CSB5/CSB6 : South Bridge and IDE option RAID */
else if ((pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) ||
@@ -531,11 +525,11 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
/* If the returned btr is the newer revision then
select the right info block */
if (serverworks_fixup_csb(pdev) == 3)
- devinfo = &info[3];
+ ppi[0] = &info[3];
/* Is this the 3rd channel CSB6 IDE ? */
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)
- ports = 1;
+ ppi[1] = &ata_dummy_port_info;
}
/* setup HT1000E */
else if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
@@ -544,8 +538,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
ata_pci_clear_simplex(pdev);
- port_info[0] = port_info[1] = devinfo;
- return ata_pci_init_one(pdev, port_info, ports);
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index a5886f061c0..440e2cb6ee7 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -232,10 +232,6 @@ static struct scsi_host_template sil680_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static struct ata_port_operations sil680_port_ops = {
@@ -345,7 +341,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &sil680_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -353,7 +349,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = 0x7f,
.port_ops = &sil680_port_ops
};
- static struct ata_port_info info_slow = {
+ static const struct ata_port_info info_slow = {
.sht = &sil680_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -361,7 +357,7 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = 0x3f,
.port_ops = &sil680_port_ops
};
- static struct ata_port_info *port_info[2] = {&info, &info};
+ const struct ata_port_info *ppi[] = { &info, NULL };
static int printed_version;
if (!printed_version++)
@@ -370,12 +366,12 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
switch(sil680_init_chip(pdev))
{
case 0:
- port_info[0] = port_info[1] = &info_slow;
+ ppi[0] = &info_slow;
break;
case 0x30:
return -ENODEV;
}
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index f5838cc1172..f2231267e01 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -38,8 +38,8 @@
#define DRV_VERSION "0.5.1"
struct sis_chipset {
- u16 device; /* PCI host ID */
- struct ata_port_info *info; /* Info block */
+ u16 device; /* PCI host ID */
+ const struct ata_port_info *info; /* Info block */
/* Probably add family, cable detect type etc here to clean
up code later */
};
@@ -524,10 +524,6 @@ static struct scsi_host_template sis_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static const struct ata_port_operations sis_133_ops = {
@@ -700,7 +696,7 @@ static const struct ata_port_operations sis_old_ops = {
.port_start = ata_port_start,
};
-static struct ata_port_info sis_info = {
+static const struct ata_port_info sis_info = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -708,7 +704,7 @@ static struct ata_port_info sis_info = {
.udma_mask = 0,
.port_ops = &sis_old_ops,
};
-static struct ata_port_info sis_info33 = {
+static const struct ata_port_info sis_info33 = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -716,35 +712,35 @@ static struct ata_port_info sis_info33 = {
.udma_mask = ATA_UDMA2, /* UDMA 33 */
.port_ops = &sis_old_ops,
};
-static struct ata_port_info sis_info66 = {
+static const struct ata_port_info sis_info66 = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA4, /* UDMA 66 */
.port_ops = &sis_66_ops,
};
-static struct ata_port_info sis_info100 = {
+static const struct ata_port_info sis_info100 = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA5,
.port_ops = &sis_100_ops,
};
-static struct ata_port_info sis_info100_early = {
+static const struct ata_port_info sis_info100_early = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.udma_mask = ATA_UDMA5,
.pio_mask = 0x1f, /* pio0-4 */
.port_ops = &sis_66_ops,
};
-struct ata_port_info sis_info133 = {
+const struct ata_port_info sis_info133 = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_ops,
};
-static struct ata_port_info sis_info133_early = {
+static const struct ata_port_info sis_info133_early = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -827,8 +823,8 @@ static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis)
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- static struct ata_port_info *port_info[2];
- struct ata_port_info *port;
+ struct ata_port_info port;
+ const struct ata_port_info *ppi[] = { &port, NULL };
struct pci_dev *host = NULL;
struct sis_chipset *chipset = NULL;
struct sis_chipset *sets;
@@ -968,13 +964,12 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (chipset == NULL)
return -ENODEV;
- port = chipset->info;
- port->private_data = chipset;
+ port = *chipset->info;
+ port.private_data = chipset;
sis_fixup(pdev, chipset);
- port_info[0] = port_info[1] = port;
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
static const struct pci_device_id sis_pci_tbl[] = {
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 9aeffdbe282..f48491ad5f3 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -301,20 +301,22 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev)
static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info_dma = {
+ static const struct ata_port_info info_dma = {
.sht = &sl82c105_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &sl82c105_port_ops
};
- static struct ata_port_info info_early = {
+ static const struct ata_port_info info_early = {
.sht = &sl82c105_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.port_ops = &sl82c105_port_ops
};
- static struct ata_port_info *port_info[2] = { &info_early, &info_early };
+ /* for now use only the first port */
+ const struct ata_port_info *ppi[] = { &info_early,
+ &ata_dummy_port_info };
u32 val;
int rev;
@@ -324,17 +326,14 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Unable to find bridge, disabling DMA.\n");
else if (rev <= 5)
dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Early bridge revision, no DMA available.\n");
- else {
- port_info[0] = &info_dma;
- port_info[1] = &info_dma;
- }
+ else
+ ppi[0] = &info_dma;
pci_read_config_dword(dev, 0x40, &val);
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
-
- return ata_pci_init_one(dev, port_info, 1); /* For now */
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id sl82c105[] = {
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index 349887bf5b9..b1d3076dfe5 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -194,10 +194,6 @@ static struct scsi_host_template triflex_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations triflex_port_ops = {
@@ -237,20 +233,20 @@ static struct ata_port_operations triflex_port_ops = {
static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- static struct ata_port_info info = {
+ static const struct ata_port_info info = {
.sht = &triflex_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &triflex_port_ops
};
- static struct ata_port_info *port_info[2] = { &info, &info };
+ const struct ata_port_info *ppi[] = { &info, NULL };
static int printed_version;
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
- return ata_pci_init_one(dev, port_info, 2);
+ return ata_pci_init_one(dev, ppi);
}
static const struct pci_device_id triflex[] = {
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 362beb2f489..e4c71f76bd5 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -301,10 +301,6 @@ static struct scsi_host_template via_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .resume = ata_scsi_device_resume,
- .suspend = ata_scsi_device_suspend,
-#endif
};
static struct ata_port_operations via_port_ops = {
@@ -425,7 +421,7 @@ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
/* Early VIA without UDMA support */
- static struct ata_port_info via_mwdma_info = {
+ static const struct ata_port_info via_mwdma_info = {
.sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
@@ -433,7 +429,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &via_port_ops
};
/* Ditto with IRQ masking required */
- static struct ata_port_info via_mwdma_info_borked = {
+ static const struct ata_port_info via_mwdma_info_borked = {
.sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
@@ -441,7 +437,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &via_port_ops_noirq,
};
/* VIA UDMA 33 devices (and borked 66) */
- static struct ata_port_info via_udma33_info = {
+ static const struct ata_port_info via_udma33_info = {
.sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
@@ -450,7 +446,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &via_port_ops
};
/* VIA UDMA 66 devices */
- static struct ata_port_info via_udma66_info = {
+ static const struct ata_port_info via_udma66_info = {
.sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
@@ -459,7 +455,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &via_port_ops
};
/* VIA UDMA 100 devices */
- static struct ata_port_info via_udma100_info = {
+ static const struct ata_port_info via_udma100_info = {
.sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
@@ -468,7 +464,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &via_port_ops
};
/* UDMA133 with bad AST (All current 133) */
- static struct ata_port_info via_udma133_info = {
+ static const struct ata_port_info via_udma133_info = {
.sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
.pio_mask = 0x1f,
@@ -476,7 +472,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.udma_mask = 0x7f, /* FIXME: should check north bridge */
.port_ops = &via_port_ops
};
- struct ata_port_info *port_info[2], *type;
+ struct ata_port_info type;
+ const struct ata_port_info *ppi[] = { &type, NULL };
struct pci_dev *isa = NULL;
const struct via_isa_bridge *config;
static int printed_version;
@@ -521,25 +518,25 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
switch(config->flags & VIA_UDMA) {
case VIA_UDMA_NONE:
if (config->flags & VIA_NO_UNMASK)
- type = &via_mwdma_info_borked;
+ type = via_mwdma_info_borked;
else
- type = &via_mwdma_info;
+ type = via_mwdma_info;
break;
case VIA_UDMA_33:
- type = &via_udma33_info;
+ type = via_udma33_info;
break;
case VIA_UDMA_66:
- type = &via_udma66_info;
+ type = via_udma66_info;
/* The 66 MHz devices require we enable the clock */
pci_read_config_dword(pdev, 0x50, &timing);
timing |= 0x80008;
pci_write_config_dword(pdev, 0x50, timing);
break;
case VIA_UDMA_100:
- type = &via_udma100_info;
+ type = via_udma100_info;
break;
case VIA_UDMA_133:
- type = &via_udma133_info;
+ type = via_udma133_info;
break;
default:
WARN_ON(1);
@@ -554,10 +551,9 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* We have established the device type, now fire it up */
- type->private_data = (void *)config;
+ type.private_data = (void *)config;
- port_info[0] = port_info[1] = type;
- return ata_pci_init_one(pdev, port_info, 2);
+ return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index b3b62e985f1..bda5e7747c2 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -135,10 +135,6 @@ static struct scsi_host_template inic_sht = {
.slave_configure = inic_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const int scr_map[] = {
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index a097595d4dc..4cea3ef7522 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -325,10 +325,6 @@ static struct scsi_host_template nv_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static struct scsi_host_template nv_adma_sht = {
@@ -347,10 +343,6 @@ static struct scsi_host_template nv_adma_sht = {
.slave_configure = nv_adma_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations nv_generic_ops = {
@@ -465,7 +457,7 @@ static const struct ata_port_operations nv_adma_ops = {
.host_stop = nv_adma_host_stop,
};
-static struct ata_port_info nv_port_info[] = {
+static const struct ata_port_info nv_port_info[] = {
/* generic */
{
.sht = &nv_sht,
@@ -1545,7 +1537,7 @@ static void nv_adma_error_handler(struct ata_port *ap)
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
- const struct ata_port_info *ppi[2];
+ const struct ata_port_info *ppi[] = { NULL, NULL };
struct ata_host *host;
struct nv_host_priv *hpriv;
int rc;
@@ -1573,8 +1565,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
type = ADMA;
}
- ppi[0] = ppi[1] = &nv_port_info[type];
- rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+ ppi[0] = &nv_port_info[type];
+ rc = ata_pci_prepare_native_host(pdev, ppi, &host);
if (rc)
return rc;
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 0a1e417f309..e8483aadd11 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -182,10 +182,6 @@ static struct scsi_host_template sil_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations sil_ops = {
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index b97ee9f31ae..a69d78cd8e9 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -380,10 +380,6 @@ static struct scsi_host_template sil24_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations sil24_ops = {
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index d8ee062e82f..ee66c5fa7ac 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -129,7 +129,7 @@ static const struct ata_port_operations sis_ops = {
.port_start = ata_port_start,
};
-static struct ata_port_info sis_port_info = {
+static const struct ata_port_info sis_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f,
.mwdma_mask = 0x7,
@@ -255,7 +255,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
struct ata_port_info pi = sis_port_info;
- const struct ata_port_info *ppi[2] = { &pi, &pi };
+ const struct ata_port_info *ppi[] = { &pi, NULL };
struct ata_host *host;
u32 genctl, val;
u8 pmr;
@@ -335,7 +335,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+ rc = ata_pci_prepare_native_host(pdev, ppi, &host);
if (rc)
return rc;
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index f74e383de08..006f5e35265 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -125,7 +125,7 @@ static const struct ata_port_operations uli_ops = {
.port_start = ata_port_start,
};
-static struct ata_port_info uli_port_info = {
+static const struct ata_port_info uli_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_IGN_SIMPLEX,
.pio_mask = 0x1f, /* pio0-4 */
@@ -201,19 +201,33 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
n_ports = 2;
if (board_idx == uli_5287)
n_ports = 4;
- rc = ata_pci_prepare_native_host(pdev, ppi, n_ports, &host);
- if (rc)
- return rc;
+
+ /* allocate the host */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+ if (!host)
+ return -ENOMEM;
hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
host->private_data = hpriv;
+ /* the first two ports are standard SFF */
+ rc = ata_pci_init_native_host(host);
+ if (rc)
+ return rc;
+
+ rc = ata_pci_init_bmdma(host);
+ if (rc)
+ return rc;
+
iomap = host->iomap;
switch (board_idx) {
case uli_5287:
+ /* If there are four, the last two live right after
+ * the standard SFF ports.
+ */
hpriv->scr_cfg_addr[0] = ULI5287_BASE;
hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 939c9246fdd..d105d2c189d 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -116,10 +116,6 @@ static struct scsi_host_template svia_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
-#ifdef CONFIG_PM
- .suspend = ata_scsi_device_suspend,
- .resume = ata_scsi_device_resume,
-#endif
};
static const struct ata_port_operations vt6420_sata_ops = {
@@ -415,7 +411,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
struct ata_host *host;
int rc;
- rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+ rc = ata_pci_prepare_native_host(pdev, ppi, &host);
if (rc)
return rc;
*r_host = host;
diff --git a/drivers/ata/sis.h b/drivers/ata/sis.h
index 231da8fc220..0f2208d8d5e 100644
--- a/drivers/ata/sis.h
+++ b/drivers/ata/sis.h
@@ -2,4 +2,4 @@
struct ata_port_info;
/* pata_sis.c */
-extern struct ata_port_info sis_info133;
+extern const struct ata_port_info sis_info133;
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 33687454eb3..f5a47a48c3b 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -2,19 +2,22 @@
# ATM device configuration
#
-menu "ATM drivers"
+menuconfig ATM_DRIVERS
+ bool "ATM drivers"
depends on NETDEVICES && ATM
+ default y
+
+if ATM_DRIVERS
config ATM_DUMMY
tristate "Dummy ATM driver"
- depends on ATM
help
Dummy ATM driver. Useful for proxy signalling, testing,
and development. If unsure, say N.
config ATM_TCP
tristate "ATM over TCP"
- depends on INET && ATM
+ depends on INET
help
ATM over TCP driver. Useful mainly for development and for
experiments. If unsure, say N.
@@ -30,7 +33,7 @@ config ATM_LANAI
config ATM_ENI
tristate "Efficient Networks ENI155P"
- depends on PCI && ATM
+ depends on PCI
---help---
Driver for the Efficient Networks ENI155p series and SMC ATM
Power155 155 Mbps ATM adapters. Both, the versions with 512KB and
@@ -139,7 +142,7 @@ config ATM_ENI_BURST_RX_2W
config ATM_FIRESTREAM
tristate "Fujitsu FireStream (FS50/FS155) "
- depends on PCI && ATM
+ depends on PCI
help
Driver for the Fujitsu FireStream 155 (MB86697) and
FireStream 50 (MB86695) ATM PCI chips.
@@ -149,7 +152,7 @@ config ATM_FIRESTREAM
config ATM_ZATM
tristate "ZeitNet ZN1221/ZN1225"
- depends on PCI && ATM
+ depends on PCI
help
Driver for the ZeitNet ZN1221 (MMF) and ZN1225 (UTP-5) 155 Mbps ATM
adapters.
@@ -169,7 +172,7 @@ config ATM_ZATM_DEBUG
config ATM_NICSTAR
tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
- depends on PCI && ATM && !64BIT
+ depends on PCI && !64BIT
help
The NICStAR chipset family is used in a large number of ATM NICs for
25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE
@@ -202,7 +205,7 @@ config ATM_NICSTAR_USE_IDT77105
config ATM_IDT77252
tristate "IDT 77252 (NICStAR II)"
- depends on PCI && ATM
+ depends on PCI
help
Driver for the IDT 77252 ATM PCI chips.
@@ -237,7 +240,7 @@ config ATM_IDT77252_USE_SUNI
config ATM_AMBASSADOR
tristate "Madge Ambassador (Collage PCI 155 Server)"
- depends on PCI && ATM
+ depends on PCI
select BITREVERSE
help
This is a driver for ATMizer based ATM card produced by Madge
@@ -262,7 +265,7 @@ config ATM_AMBASSADOR_DEBUG
config ATM_HORIZON
tristate "Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)"
- depends on PCI && ATM
+ depends on PCI
help
This is a driver for the Horizon chipset ATM adapter cards once
produced by Madge Networks Ltd. Say Y (or M to compile as a module
@@ -286,7 +289,7 @@ config ATM_HORIZON_DEBUG
config ATM_IA
tristate "Interphase ATM PCI x575/x525/x531"
- depends on PCI && ATM && !64BIT
+ depends on PCI && !64BIT
---help---
This is a driver for the Interphase (i)ChipSAR adapter cards
which include a variety of variants in term of the size of the
@@ -319,7 +322,7 @@ config ATM_IA_DEBUG
config ATM_FORE200E_MAYBE
tristate "FORE Systems 200E-series"
- depends on (PCI || SBUS) && ATM
+ depends on PCI || SBUS
---help---
This is a driver for the FORE Systems 200E-series ATM adapter
cards. It simultaneously supports PCA-200E and SBA-200E models
@@ -436,7 +439,7 @@ config ATM_FORE200E
config ATM_HE
tristate "ForeRunner HE Series"
- depends on PCI && ATM
+ depends on PCI
help
This is a driver for the Marconi ForeRunner HE-series ATM adapter
cards. It simultaneously supports the 155 and 622 versions.
@@ -448,5 +451,4 @@ config ATM_HE_USE_SUNI
Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner
HE cards. This driver provides carrier detection some statistics.
-endmenu
-
+endif # ATM
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 18cdd8c7762..e2fc4b6734c 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1317,18 +1317,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
}
#endif
-static struct loop_device *loop_find_dev(int number)
-{
- struct loop_device *lo;
-
- list_for_each_entry(lo, &loop_devices, lo_list) {
- if (lo->lo_number == number)
- return lo;
- }
- return NULL;
-}
-
-static struct loop_device *loop_init_one(int i);
static int lo_open(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1337,11 +1325,6 @@ static int lo_open(struct inode *inode, struct file *file)
lo->lo_refcnt++;
mutex_unlock(&lo->lo_ctl_mutex);
- mutex_lock(&loop_devices_mutex);
- if (!loop_find_dev(lo->lo_number + 1))
- loop_init_one(lo->lo_number + 1);
- mutex_unlock(&loop_devices_mutex);
-
return 0;
}
@@ -1448,7 +1431,7 @@ out_free_queue:
out_free_dev:
kfree(lo);
out:
- return ERR_PTR(-ENOMEM);
+ return NULL;
}
static void loop_del_one(struct loop_device *lo)
@@ -1460,36 +1443,30 @@ static void loop_del_one(struct loop_device *lo)
kfree(lo);
}
+static int loop_lock(dev_t dev, void *data)
+{
+ mutex_lock(&loop_devices_mutex);
+ return 0;
+}
+
static struct kobject *loop_probe(dev_t dev, int *part, void *data)
{
- unsigned int number = dev & MINORMASK;
- struct loop_device *lo;
+ struct loop_device *lo = loop_init_one(dev & MINORMASK);
+ struct kobject *kobj;
- mutex_lock(&loop_devices_mutex);
- lo = loop_find_dev(number);
- if (lo == NULL)
- lo = loop_init_one(number);
+ kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM);
mutex_unlock(&loop_devices_mutex);
*part = 0;
- if (IS_ERR(lo))
- return (void *)lo;
- else
- return &lo->lo_disk->kobj;
+ return kobj;
}
static int __init loop_init(void)
{
- struct loop_device *lo;
-
if (register_blkdev(LOOP_MAJOR, "loop"))
return -EIO;
blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
- THIS_MODULE, loop_probe, NULL, NULL);
-
- lo = loop_init_one(0);
- if (IS_ERR(lo))
- goto out;
+ THIS_MODULE, loop_probe, loop_lock, NULL);
if (max_loop) {
printk(KERN_INFO "loop: the max_loop option is obsolete "
@@ -1498,11 +1475,6 @@ static int __init loop_init(void)
}
printk(KERN_INFO "loop: module loaded\n");
return 0;
-
-out:
- unregister_blkdev(LOOP_MAJOR, "loop");
- printk(KERN_ERR "loop: ran out of memory\n");
- return -ENOMEM;
}
static void __exit loop_exit(void)
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 0f4203b499a..6055b9c0ac0 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -307,7 +307,9 @@ static void hci_uart_tty_close(struct tty_struct *tty)
if (hu) {
struct hci_dev *hdev = hu->hdev;
- hci_uart_close(hdev);
+
+ if (hdev)
+ hci_uart_close(hdev);
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
hu->proto->close(hu);
@@ -473,12 +475,18 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
tty->low_latency = 1;
} else
return -EBUSY;
+ break;
case HCIUARTGETPROTO:
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
return hu->proto->id;
return -EUNATCH;
+ case HCIUARTGETDEVICE:
+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
+ return hu->hdev->id;
+ return -EUNATCH;
+
default:
err = n_tty_ioctl(tty, file, cmd, arg);
break;
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index b250e6789de..1097ce72393 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -28,8 +28,9 @@
#endif
/* Ioctls */
-#define HCIUARTSETPROTO _IOW('U', 200, int)
-#define HCIUARTGETPROTO _IOR('U', 201, int)
+#define HCIUARTSETPROTO _IOW('U', 200, int)
+#define HCIUARTGETPROTO _IOR('U', 201, int)
+#define HCIUARTGETDEVICE _IOR('U', 202, int)
/* UART protocols */
#define HCI_UART_MAX_PROTO 4
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index c9f0f250d78..801abdd2906 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -268,7 +268,7 @@ static int __devinit aperture_valid(u64 aper, u32 size)
printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20);
return 0;
}
- if (aper + size > 0xffffffff) {
+ if ((u64)aper + size > 0x100000000ULL) {
printk(KERN_ERR PFX "Aperture out of bounds\n");
return 0;
}
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 6c5d15de331..78e1b962fe3 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1915,10 +1915,10 @@ static __devinit int try_init_acpi(struct SPMITable *spmi)
if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
info->io_setup = mem_setup;
- info->io.addr_type = IPMI_IO_ADDR_SPACE;
+ info->io.addr_type = IPMI_MEM_ADDR_SPACE;
} else if (spmi->addr.space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
info->io_setup = port_setup;
- info->io.addr_type = IPMI_MEM_ADDR_SPACE;
+ info->io.addr_type = IPMI_IO_ADDR_SPACE;
} else {
kfree(info);
printk("ipmi_si: Unknown ACPI I/O Address type\n");
@@ -2974,6 +2974,10 @@ static __devinit int init_ipmi_si(void)
#ifdef CONFIG_PCI
pci_unregister_driver(&ipmi_pci_driver);
#endif
+
+#ifdef CONFIG_PPC_OF
+ of_unregister_platform_driver(&ipmi_of_platform_driver);
+#endif
driver_unregister(&ipmi_driver);
printk("ipmi_si: Unable to find any System Interface(s)\n");
return -ENODEV;
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 6ac3ca4c723..b3d4ccc33a4 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1544,21 +1544,18 @@ static unsigned int normal_poll(struct tty_struct * tty, struct file * file, pol
}
struct tty_ldisc tty_ldisc_N_TTY = {
- TTY_LDISC_MAGIC, /* magic */
- "n_tty", /* name */
- 0, /* num */
- 0, /* flags */
- n_tty_open, /* open */
- n_tty_close, /* close */
- n_tty_flush_buffer, /* flush_buffer */
- n_tty_chars_in_buffer, /* chars_in_buffer */
- read_chan, /* read */
- write_chan, /* write */
- n_tty_ioctl, /* ioctl */
- n_tty_set_termios, /* set_termios */
- normal_poll, /* poll */
- NULL, /* hangup */
- n_tty_receive_buf, /* receive_buf */
- n_tty_write_wakeup /* write_wakeup */
+ .magic = TTY_LDISC_MAGIC,
+ .name = "n_tty",
+ .open = n_tty_open,
+ .close = n_tty_close,
+ .flush_buffer = n_tty_flush_buffer,
+ .chars_in_buffer = n_tty_chars_in_buffer,
+ .read = read_chan,
+ .write = write_chan,
+ .ioctl = n_tty_ioctl,
+ .set_termios = n_tty_set_termios,
+ .poll = normal_poll,
+ .receive_buf = n_tty_receive_buf,
+ .write_wakeup = n_tty_write_wakeup
};
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 245f03195b7..8cc60b69346 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -402,7 +402,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Host number %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name);
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup);
- if (Rup >= (unsigned short) MAX_RUP) {
+ if (Rup < (unsigned short) MAX_RUP) {
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", HostP->Mapping[Rup].Name);
} else
rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name);
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 61a63da420c..a3fd7e7ba5a 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -1014,9 +1014,6 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
/*
* Info->count is now 1; so it's safe to sleep now.
*/
- info->session = process_session(current);
- info->pgrp = process_group(current);
-
if ((info->flags & ROCKET_INITIALIZED) == 0) {
cp = &info->channel;
sSetRxTrigger(cp, TRIG_1);
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 89b4d7b10d1..b4c53dfa795 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1158,8 +1158,6 @@ struct r_port {
int xmit_head;
int xmit_tail;
int xmit_cnt;
- int session;
- int pgrp;
int cd_status;
int ignore_status_mask;
int read_status_mask;
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index 2f56e8c5489..1b75b0b7d54 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -203,8 +203,6 @@ scdrv_dispatch_event(char *event, int len)
class = (code & EV_CLASS_MASK);
if (class == EV_CLASS_PWRD_NOTIFY || code == ENV_PWRDN_PEND) {
- struct task_struct *p;
-
if (snsc_shutting_down)
return;
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 2a7736b5f2f..02b49bc0002 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1171,6 +1171,112 @@ static int ioctl(struct tty_struct *tty, struct file *file,
}
/*
+ * support for 32 bit ioctl calls on 64 bit systems
+ */
+#ifdef CONFIG_COMPAT
+static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *user_params)
+{
+ struct MGSL_PARAMS32 tmp_params;
+
+ DBGINFO(("%s get_params32\n", info->device_name));
+ tmp_params.mode = (compat_ulong_t)info->params.mode;
+ tmp_params.loopback = info->params.loopback;
+ tmp_params.flags = info->params.flags;
+ tmp_params.encoding = info->params.encoding;
+ tmp_params.clock_speed = (compat_ulong_t)info->params.clock_speed;
+ tmp_params.addr_filter = info->params.addr_filter;
+ tmp_params.crc_type = info->params.crc_type;
+ tmp_params.preamble_length = info->params.preamble_length;
+ tmp_params.preamble = info->params.preamble;
+ tmp_params.data_rate = (compat_ulong_t)info->params.data_rate;
+ tmp_params.data_bits = info->params.data_bits;
+ tmp_params.stop_bits = info->params.stop_bits;
+ tmp_params.parity = info->params.parity;
+ if (copy_to_user(user_params, &tmp_params, sizeof(struct MGSL_PARAMS32)))
+ return -EFAULT;
+ return 0;
+}
+
+static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *new_params)
+{
+ struct MGSL_PARAMS32 tmp_params;
+
+ DBGINFO(("%s set_params32\n", info->device_name));
+ if (copy_from_user(&tmp_params, new_params, sizeof(struct MGSL_PARAMS32)))
+ return -EFAULT;
+
+ spin_lock(&info->lock);
+ info->params.mode = tmp_params.mode;
+ info->params.loopback = tmp_params.loopback;
+ info->params.flags = tmp_params.flags;
+ info->params.encoding = tmp_params.encoding;
+ info->params.clock_speed = tmp_params.clock_speed;
+ info->params.addr_filter = tmp_params.addr_filter;
+ info->params.crc_type = tmp_params.crc_type;
+ info->params.preamble_length = tmp_params.preamble_length;
+ info->params.preamble = tmp_params.preamble;
+ info->params.data_rate = tmp_params.data_rate;
+ info->params.data_bits = tmp_params.data_bits;
+ info->params.stop_bits = tmp_params.stop_bits;
+ info->params.parity = tmp_params.parity;
+ spin_unlock(&info->lock);
+
+ change_params(info);
+
+ return 0;
+}
+
+static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct slgt_info *info = tty->driver_data;
+ int rc = -ENOIOCTLCMD;
+
+ if (sanity_check(info, tty->name, "compat_ioctl"))
+ return -ENODEV;
+ DBGINFO(("%s compat_ioctl() cmd=%08X\n", info->device_name, cmd));
+
+ switch (cmd) {
+
+ case MGSL_IOCSPARAMS32:
+ rc = set_params32(info, compat_ptr(arg));
+ break;
+
+ case MGSL_IOCGPARAMS32:
+ rc = get_params32(info, compat_ptr(arg));
+ break;
+
+ case MGSL_IOCGPARAMS:
+ case MGSL_IOCSPARAMS:
+ case MGSL_IOCGTXIDLE:
+ case MGSL_IOCGSTATS:
+ case MGSL_IOCWAITEVENT:
+ case MGSL_IOCGIF:
+ case MGSL_IOCSGPIO:
+ case MGSL_IOCGGPIO:
+ case MGSL_IOCWAITGPIO:
+ case TIOCGICOUNT:
+ rc = ioctl(tty, file, cmd, (unsigned long)(compat_ptr(arg)));
+ break;
+
+ case MGSL_IOCSTXIDLE:
+ case MGSL_IOCTXENABLE:
+ case MGSL_IOCRXENABLE:
+ case MGSL_IOCTXABORT:
+ case TIOCMIWAIT:
+ case MGSL_IOCSIF:
+ rc = ioctl(tty, file, cmd, arg);
+ break;
+ }
+
+ DBGINFO(("%s compat_ioctl() cmd=%08X rc=%d\n", info->device_name, cmd, rc));
+ return rc;
+}
+#else
+#define slgt_compat_ioctl NULL
+#endif /* ifdef CONFIG_COMPAT */
+
+/*
* proc fs support
*/
static inline int line_info(char *buf, struct slgt_info *info)
@@ -3446,6 +3552,7 @@ static const struct tty_operations ops = {
.chars_in_buffer = chars_in_buffer,
.flush_buffer = flush_buffer,
.ioctl = ioctl,
+ .compat_ioctl = slgt_compat_ioctl,
.throttle = throttle,
.unthrottle = unthrottle,
.send_xchar = send_xchar,
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
index c912d8691cb..9363bcf0a40 100644
--- a/drivers/char/tpm/tpm_atmel.h
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -23,6 +23,9 @@
*/
#ifdef CONFIG_PPC64
+
+#include <asm/prom.h>
+
#define atmel_getb(chip, offset) readb(chip->vendor->iobase + offset);
#define atmel_putb(val, chip, offset) writeb(val, chip->vendor->iobase + offset)
#define atmel_request_region request_mem_region
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index fc662e4ce58..75d2a46e106 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -151,6 +151,12 @@ static int tty_open(struct inode *, struct file *);
static int tty_release(struct inode *, struct file *);
int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long tty_compat_ioctl(struct file * file, unsigned int cmd,
+ unsigned long arg);
+#else
+#define tty_compat_ioctl NULL
+#endif
static int tty_fasync(int fd, struct file * filp, int on);
static void release_tty(struct tty_struct *tty, int idx);
static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
@@ -363,6 +369,29 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
}
/**
+ * tty_buffer_flush - flush full tty buffers
+ * @tty: tty to flush
+ *
+ * flush all the buffers containing receive data
+ *
+ * Locking: none
+ */
+
+static void tty_buffer_flush(struct tty_struct *tty)
+{
+ struct tty_buffer *thead;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tty->buf.lock, flags);
+ while((thead = tty->buf.head) != NULL) {
+ tty->buf.head = thead->next;
+ tty_buffer_free(tty, thead);
+ }
+ tty->buf.tail = NULL;
+ spin_unlock_irqrestore(&tty->buf.lock, flags);
+}
+
+/**
* tty_buffer_find - find a free tty buffer
* @tty: tty owning the buffer
* @size: characters wanted
@@ -1143,8 +1172,8 @@ static unsigned int hung_up_tty_poll(struct file * filp, poll_table * wait)
return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
}
-static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
- unsigned int cmd, unsigned long arg)
+static long hung_up_tty_ioctl(struct file * file,
+ unsigned int cmd, unsigned long arg)
{
return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
}
@@ -1155,6 +1184,7 @@ static const struct file_operations tty_fops = {
.write = tty_write,
.poll = tty_poll,
.ioctl = tty_ioctl,
+ .compat_ioctl = tty_compat_ioctl,
.open = tty_open,
.release = tty_release,
.fasync = tty_fasync,
@@ -1167,6 +1197,7 @@ static const struct file_operations ptmx_fops = {
.write = tty_write,
.poll = tty_poll,
.ioctl = tty_ioctl,
+ .compat_ioctl = tty_compat_ioctl,
.open = ptmx_open,
.release = tty_release,
.fasync = tty_fasync,
@@ -1179,6 +1210,7 @@ static const struct file_operations console_fops = {
.write = redirected_tty_write,
.poll = tty_poll,
.ioctl = tty_ioctl,
+ .compat_ioctl = tty_compat_ioctl,
.open = tty_open,
.release = tty_release,
.fasync = tty_fasync,
@@ -1189,7 +1221,8 @@ static const struct file_operations hung_up_tty_fops = {
.read = hung_up_tty_read,
.write = hung_up_tty_write,
.poll = hung_up_tty_poll,
- .ioctl = hung_up_tty_ioctl,
+ .unlocked_ioctl = hung_up_tty_ioctl,
+ .compat_ioctl = hung_up_tty_ioctl,
.release = tty_release,
};
@@ -1238,6 +1271,7 @@ void tty_ldisc_flush(struct tty_struct *tty)
ld->flush_buffer(tty);
tty_ldisc_deref(ld);
}
+ tty_buffer_flush(tty);
}
EXPORT_SYMBOL_GPL(tty_ldisc_flush);
@@ -3340,6 +3374,15 @@ int tty_ioctl(struct inode * inode, struct file * file,
case TIOCMBIC:
case TIOCMBIS:
return tty_tiocmset(tty, file, cmd, p);
+ case TCFLSH:
+ switch (arg) {
+ case TCIFLUSH:
+ case TCIOFLUSH:
+ /* flush tty buffer and allow ldisc to process ioctl */
+ tty_buffer_flush(tty);
+ break;
+ }
+ break;
}
if (tty->driver->ioctl) {
retval = (tty->driver->ioctl)(tty, file, cmd, arg);
@@ -3357,6 +3400,32 @@ int tty_ioctl(struct inode * inode, struct file * file,
return retval;
}
+#ifdef CONFIG_COMPAT
+static long tty_compat_ioctl(struct file * file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct tty_struct *tty = file->private_data;
+ struct tty_ldisc *ld;
+ int retval = -ENOIOCTLCMD;
+
+ if (tty_paranoia_check(tty, inode, "tty_ioctl"))
+ return -EINVAL;
+
+ if (tty->driver->compat_ioctl) {
+ retval = (tty->driver->compat_ioctl)(tty, file, cmd, arg);
+ if (retval != -ENOIOCTLCMD)
+ return retval;
+ }
+
+ ld = tty_ldisc_ref_wait(tty);
+ if (ld->compat_ioctl)
+ retval = ld->compat_ioctl(tty, file, cmd, arg);
+ tty_ldisc_deref(ld);
+
+ return retval;
+}
+#endif
/*
* This implements the "Secure Attention Key" --- the idea is to
@@ -3689,6 +3758,7 @@ void tty_set_operations(struct tty_driver *driver,
driver->write_room = op->write_room;
driver->chars_in_buffer = op->chars_in_buffer;
driver->ioctl = op->ioctl;
+ driver->compat_ioctl = op->compat_ioctl;
driver->set_termios = op->set_termios;
driver->throttle = op->throttle;
driver->unthrottle = op->unthrottle;
@@ -3843,6 +3913,7 @@ void proc_clear_tty(struct task_struct *p)
p->signal->tty = NULL;
spin_unlock_irq(&p->sighand->siglock);
}
+EXPORT_SYMBOL(proc_clear_tty);
static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
index 3c9684ccd2f..eac4f9b9f00 100644
--- a/drivers/char/watchdog/iTCO_wdt.c
+++ b/drivers/char/watchdog/iTCO_wdt.c
@@ -571,7 +571,7 @@ static int iTCO_wdt_init(struct pci_dev *pdev, const struct pci_device_id *ent,
* ACPIBASE is bits [15:7] from 0x40-0x43
*/
pci_read_config_dword(pdev, 0x40, &base_address);
- base_address &= 0x00007f80;
+ base_address &= 0x0000ff80;
if (base_address == 0x00000000) {
/* Something's wrong here, ACPIBASE has to be set */
printk(KERN_ERR PFX "failed to get TCOBASE address\n");
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index a19b65ed311..7f817897b17 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -240,11 +240,94 @@ static inline void hidinput_pb_setup(struct input_dev *input)
}
#endif
+static inline int match_scancode(int code, int scancode)
+{
+ if (scancode == 0)
+ return 1;
+ return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode);
+}
+
+static inline int match_keycode(int code, int keycode)
+{
+ if (keycode == 0)
+ return 1;
+ return (code == keycode);
+}
+
+static struct hid_usage *hidinput_find_key(struct hid_device *hid,
+ int scancode, int keycode)
+{
+ int i, j, k;
+ struct hid_report *report;
+ struct hid_usage *usage;
+
+ for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+ list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
+ for (i = 0; i < report->maxfield; i++) {
+ for ( j = 0; j < report->field[i]->maxusage; j++) {
+ usage = report->field[i]->usage + j;
+ if (usage->type == EV_KEY &&
+ match_scancode(usage->hid, scancode) &&
+ match_keycode(usage->code, keycode))
+ return usage;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+static int hidinput_getkeycode(struct input_dev *dev, int scancode,
+ int *keycode)
+{
+ struct hid_device *hid = dev->private;
+ struct hid_usage *usage;
+
+ usage = hidinput_find_key(hid, scancode, 0);
+ if (usage) {
+ *keycode = usage->code;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int hidinput_setkeycode(struct input_dev *dev, int scancode,
+ int keycode)
+{
+ struct hid_device *hid = dev->private;
+ struct hid_usage *usage;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ usage = hidinput_find_key(hid, scancode, 0);
+ if (usage) {
+ old_keycode = usage->code;
+ usage->code = keycode;
+
+ clear_bit(old_keycode, dev->keybit);
+ set_bit(usage->code, dev->keybit);
+#ifdef CONFIG_HID_DEBUG
+ printk (KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode);
+#endif
+ /* Set the keybit for the old keycode if the old keycode is used
+ * by another key */
+ if (hidinput_find_key (hid, 0, old_keycode))
+ set_bit(old_keycode, dev->keybit);
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage)
{
struct input_dev *input = hidinput->input;
- struct hid_device *device = input->private;
+ struct hid_device *device = input_get_drvdata(input);
int max = 0, code;
unsigned long *bit = NULL;
@@ -553,6 +636,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x1015: map_key_clear(KEY_RECORD); break;
case 0x1016: map_key_clear(KEY_PLAYER); break;
case 0x1017: map_key_clear(KEY_EJECTCD); break;
+ case 0x1018: map_key_clear(KEY_MEDIA); break;
case 0x1019: map_key_clear(KEY_PROG1); break;
case 0x101a: map_key_clear(KEY_PROG2); break;
case 0x101b: map_key_clear(KEY_PROG3); break;
@@ -560,9 +644,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x1020: map_key_clear(KEY_ZOOMOUT); break;
case 0x1021: map_key_clear(KEY_ZOOMRESET); break;
case 0x1023: map_key_clear(KEY_CLOSE); break;
+ case 0x1027: map_key_clear(KEY_MENU); break;
/* this one is marked as 'Rotate' */
case 0x1028: map_key_clear(KEY_ANGLE); break;
case 0x1029: map_key_clear(KEY_SHUFFLE); break;
+ case 0x102a: map_key_clear(KEY_BACK); break;
+ case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break;
case 0x1041: map_key_clear(KEY_BATTERY); break;
case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break;
case 0x1043: map_key_clear(KEY_SPREADSHEET); break;
@@ -855,13 +942,15 @@ EXPORT_SYMBOL_GPL(hidinput_find_field);
static int hidinput_open(struct input_dev *dev)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
+
return hid->hid_open(hid);
}
static void hidinput_close(struct input_dev *dev)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
+
hid->hid_close(hid);
}
@@ -909,10 +998,12 @@ int hidinput_connect(struct hid_device *hid)
return -1;
}
- input_dev->private = hid;
+ input_set_drvdata(input_dev, hid);
input_dev->event = hid->hidinput_input_event;
input_dev->open = hidinput_open;
input_dev->close = hidinput_close;
+ input_dev->setkeycode = hidinput_setkeycode;
+ input_dev->getkeycode = hidinput_getkeycode;
input_dev->name = hid->name;
input_dev->phys = hid->phys;
@@ -921,7 +1012,7 @@ int hidinput_connect(struct hid_device *hid)
input_dev->id.vendor = hid->vendor;
input_dev->id.product = hid->product;
input_dev->id.version = hid->version;
- input_dev->cdev.dev = hid->dev;
+ input_dev->dev.parent = hid->dev;
hidinput->input = input_dev;
list_add_tail(&hidinput->list, &hid->inputs);
}
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 7c87bdc538b..1b4b572f899 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -25,12 +25,12 @@ comment "Input core support is needed for USB HID input layer or HIDBP support"
depends on USB_HID && INPUT=n
config USB_HIDINPUT_POWERBOOK
- bool "Enable support for iBook/PowerBook special keys"
+ bool "Enable support for iBook/PowerBook/MacBook/MacBookPro special keys"
default n
depends on USB_HID
help
Say Y here if you want support for the special keys (Fn, Numlock) on
- Apple iBooks and PowerBooks.
+ Apple iBooks, PowerBooks, MacBooks and MacBook Pros.
If unsure, say N.
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 91d610358d5..d91b9dac6df 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -446,7 +446,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
struct hid_field *field;
int offset;
@@ -626,14 +626,10 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
- if (usbhid->inbuf)
- usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
- if (usbhid->outbuf)
- usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
- if (usbhid->cr)
- usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
- if (usbhid->ctrlbuf)
- usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
+ usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
+ usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
+ usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
+ usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
}
/*
@@ -692,6 +688,30 @@ static void hid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
}
}
+/*
+ * Some USB barcode readers from cypress have usage min and usage max in
+ * the wrong order
+ */
+static void hid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
+{
+ short fixed = 0;
+ int i;
+
+ for (i = 0; i < rsize - 4; i++) {
+ if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
+ unsigned char tmp;
+
+ rdesc[i] = 0x19; rdesc[i+2] = 0x29;
+ tmp = rdesc[i+3];
+ rdesc[i+3] = rdesc[i+1];
+ rdesc[i+1] = tmp;
+ }
+ }
+
+ if (fixed)
+ info("Fixing up Cypress report descriptor");
+}
+
static struct hid_device *usb_hid_configure(struct usb_interface *intf)
{
struct usb_host_interface *interface = intf->cur_altsetting;
@@ -758,6 +778,9 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
if (quirks & HID_QUIRK_LOGITECH_DESCRIPTOR)
hid_fixup_logitech_descriptor(rdesc, rsize);
+ if (quirks & HID_QUIRK_SWAPPED_MIN_MAX)
+ hid_fixup_cypress_descriptor(rdesc, rsize);
+
#ifdef CONFIG_HID_DEBUG
printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
for (n = 0; n < rsize; n++)
diff --git a/drivers/hid/usbhid/hid-lgff.c b/drivers/hid/usbhid/hid-lgff.c
index 92d2553f17b..c5cd4107d6a 100644
--- a/drivers/hid/usbhid/hid-lgff.c
+++ b/drivers/hid/usbhid/hid-lgff.c
@@ -60,7 +60,7 @@ static const struct dev_type devices[] = {
static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
int x, y;
diff --git a/drivers/hid/usbhid/hid-plff.c b/drivers/hid/usbhid/hid-plff.c
index 76d2e6e14db..d6a8f2b49bd 100644
--- a/drivers/hid/usbhid/hid-plff.c
+++ b/drivers/hid/usbhid/hid-plff.c
@@ -37,7 +37,7 @@ struct plff_device {
static int hid_plff_play(struct input_dev *dev, void *data,
struct ff_effect *effect)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
struct plff_device *plff = data;
int left, right;
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 17a87555e32..f6c4145dc20 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -92,6 +92,8 @@
#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
+#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
+#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
#define USB_VENDOR_ID_DELL 0x413c
#define USB_DEVICE_ID_DELL_W7658 0x2005
@@ -193,6 +195,7 @@
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
+#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
@@ -422,6 +425,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
@@ -445,6 +449,9 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
+ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_SWAPPED_MIN_MAX },
+ { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_SWAPPED_MIN_MAX },
+
{ 0, 0 }
};
diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c
index ab67331620d..ab5ba6ef891 100644
--- a/drivers/hid/usbhid/hid-tmff.c
+++ b/drivers/hid/usbhid/hid-tmff.c
@@ -59,7 +59,7 @@ static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
struct tmff_device *tmff = data;
int left, right; /* Rumbling */
diff --git a/drivers/hid/usbhid/hid-zpff.c b/drivers/hid/usbhid/hid-zpff.c
index 7bd8238ca21..a7fbffcdaf3 100644
--- a/drivers/hid/usbhid/hid-zpff.c
+++ b/drivers/hid/usbhid/hid-zpff.c
@@ -37,7 +37,7 @@ struct zpff_device {
static int hid_zpff_play(struct input_dev *dev, void *data,
struct ff_effect *effect)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
struct zpff_device *zpff = data;
int left, right;
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index a8b3d66cd49..488d61bdbf2 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -51,6 +51,7 @@ struct hiddev {
wait_queue_head_t wait;
struct hid_device *hid;
struct list_head list;
+ spinlock_t list_lock;
};
struct hiddev_list {
@@ -161,7 +162,9 @@ static void hiddev_send_event(struct hid_device *hid,
{
struct hiddev *hiddev = hid->hiddev;
struct hiddev_list *list;
+ unsigned long flags;
+ spin_lock_irqsave(&hiddev->list_lock, flags);
list_for_each_entry(list, &hiddev->list, node) {
if (uref->field_index != HID_FIELD_INDEX_NONE ||
(list->flags & HIDDEV_FLAG_REPORT) != 0) {
@@ -171,6 +174,7 @@ static void hiddev_send_event(struct hid_device *hid,
kill_fasync(&list->fasync, SIGIO, POLL_IN);
}
}
+ spin_unlock_irqrestore(&hiddev->list_lock, flags);
wake_up_interruptible(&hiddev->wait);
}
@@ -235,9 +239,13 @@ static int hiddev_fasync(int fd, struct file *file, int on)
static int hiddev_release(struct inode * inode, struct file * file)
{
struct hiddev_list *list = file->private_data;
+ unsigned long flags;
hiddev_fasync(-1, file, 0);
+
+ spin_lock_irqsave(&list->hiddev->list_lock, flags);
list_del(&list->node);
+ spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
if (!--list->hiddev->open) {
if (list->hiddev->exist)
@@ -257,6 +265,7 @@ static int hiddev_release(struct inode * inode, struct file * file)
static int hiddev_open(struct inode *inode, struct file *file)
{
struct hiddev_list *list;
+ unsigned long flags;
int i = iminor(inode) - HIDDEV_MINOR_BASE;
@@ -267,7 +276,11 @@ static int hiddev_open(struct inode *inode, struct file *file)
return -ENOMEM;
list->hiddev = hiddev_table[i];
+
+ spin_lock_irqsave(&list->hiddev->list_lock, flags);
list_add_tail(&list->node, &hiddev_table[i]->list);
+ spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
+
file->private_data = list;
if (!list->hiddev->open++)
@@ -773,6 +786,7 @@ int hiddev_connect(struct hid_device *hid)
init_waitqueue_head(&hiddev->wait);
INIT_LIST_HEAD(&hiddev->list);
+ spin_lock_init(&hiddev->list_lock);
hiddev->hid = hid;
hiddev->exist = 1;
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index 65aa12e8d7b..13097878071 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -133,12 +133,11 @@ resubmit:
static int usb_kbd_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
- struct usb_kbd *kbd = dev->private;
+ struct usb_kbd *kbd = input_get_drvdata(dev);
if (type != EV_LED)
return -1;
-
kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
(!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
(!!test_bit(LED_NUML, dev->led));
@@ -175,7 +174,7 @@ static void usb_kbd_led(struct urb *urb)
static int usb_kbd_open(struct input_dev *dev)
{
- struct usb_kbd *kbd = dev->private;
+ struct usb_kbd *kbd = input_get_drvdata(dev);
kbd->irq->dev = kbd->usbdev;
if (usb_submit_urb(kbd->irq, GFP_KERNEL))
@@ -186,7 +185,7 @@ static int usb_kbd_open(struct input_dev *dev)
static void usb_kbd_close(struct input_dev *dev)
{
- struct usb_kbd *kbd = dev->private;
+ struct usb_kbd *kbd = input_get_drvdata(dev);
usb_kill_urb(kbd->irq);
}
@@ -211,12 +210,9 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
{
usb_free_urb(kbd->irq);
usb_free_urb(kbd->led);
- if (kbd->new)
- usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
- if (kbd->cr)
- usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
- if (kbd->leds)
- usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
+ usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
+ usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
+ usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
}
static int usb_kbd_probe(struct usb_interface *iface,
@@ -274,8 +270,9 @@ static int usb_kbd_probe(struct usb_interface *iface,
input_dev->name = kbd->name;
input_dev->phys = kbd->phys;
usb_to_input_id(dev, &input_dev->id);
- input_dev->cdev.dev = &iface->dev;
- input_dev->private = kbd;
+ input_dev->dev.parent = &iface->dev;
+
+ input_set_drvdata(input_dev, kbd);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
index 573776d865e..5345c73bcf6 100644
--- a/drivers/hid/usbhid/usbmouse.c
+++ b/drivers/hid/usbhid/usbmouse.c
@@ -96,7 +96,7 @@ resubmit:
static int usb_mouse_open(struct input_dev *dev)
{
- struct usb_mouse *mouse = dev->private;
+ struct usb_mouse *mouse = input_get_drvdata(dev);
mouse->irq->dev = mouse->usbdev;
if (usb_submit_urb(mouse->irq, GFP_KERNEL))
@@ -107,7 +107,7 @@ static int usb_mouse_open(struct input_dev *dev)
static void usb_mouse_close(struct input_dev *dev)
{
- struct usb_mouse *mouse = dev->private;
+ struct usb_mouse *mouse = input_get_drvdata(dev);
usb_kill_urb(mouse->irq);
}
@@ -171,7 +171,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
input_dev->name = mouse->name;
input_dev->phys = mouse->phys;
usb_to_input_id(dev, &input_dev->id);
- input_dev->cdev.dev = &intf->dev;
+ input_dev->dev.parent = &intf->dev;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
@@ -179,7 +179,8 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
input_dev->relbit[0] |= BIT(REL_WHEEL);
- input_dev->private = mouse;
+ input_set_drvdata(input_dev, mouse);
+
input_dev->open = usb_mouse_open;
input_dev->close = usb_mouse_close;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 55a72592704..b234729706b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -336,7 +336,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
if (compat) {
len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
- if (len < maxlen)
+ if (len > maxlen)
len = maxlen;
for (i = 0; i < len / sizeof(compat_long_t); i++)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 65814b0340c..c10ce91b64e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5103,7 +5103,7 @@ static int is_mddev_idle(mddev_t *mddev)
*
* Note: the following is an unsigned comparison.
*/
- if ((curr_events - rdev->last_events + 4096) > 8192) {
+ if ((long)curr_events - (long)rdev->last_events > 4096) {
rdev->last_events = curr_events;
idle = 0;
}
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 3a80e0cc736..624b21cef5b 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -87,6 +87,14 @@ config VIDEO_TVEEPROM
tristate
depends on I2C
+config DAB
+ boolean "DAB adapters"
+ default y
+ ---help---
+ Allow selecting support for for Digital Audio Broadcasting (DAB)
+ Receiver adapters.
+
+if DAB
config USB_DABUSB
tristate "DABUSB driver"
depends on USB
@@ -100,5 +108,6 @@ config USB_DABUSB
To compile this driver as a module, choose M here: the
module will be called dabusb.
+endif # DAB
endmenu
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index c578a529e7a..8fa19939c2b 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -5,4 +5,4 @@
obj-y := common/
obj-$(CONFIG_VIDEO_DEV) += video/
obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-$(CONFIG_DVB) += dvb/
+obj-$(CONFIG_DVB_CORE) += dvb/
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 86cbdbcf9d7..ef3e54cd940 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -136,28 +136,45 @@ char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa
char *mem = vmalloc_32(length);
int slen = 0;
- if (NULL == mem) {
- return NULL;
- }
+ if (NULL == mem)
+ goto err_null;
- if (!(pt->slist = vmalloc_to_sg(mem, pages))) {
- vfree(mem);
- return NULL;
- }
+ if (!(pt->slist = vmalloc_to_sg(mem, pages)))
+ goto err_free_mem;
- if (saa7146_pgtable_alloc(pci, pt)) {
- kfree(pt->slist);
- pt->slist = NULL;
- vfree(mem);
- return NULL;
- }
+ if (saa7146_pgtable_alloc(pci, pt))
+ goto err_free_slist;
- slen = pci_map_sg(pci,pt->slist,pages,PCI_DMA_FROMDEVICE);
- if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) {
- return NULL;
- }
+ pt->nents = pages;
+ slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
+ if (0 == slen)
+ goto err_free_pgtable;
+
+ if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
+ goto err_unmap_sg;
return mem;
+
+err_unmap_sg:
+ pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+err_free_pgtable:
+ saa7146_pgtable_free(pci, pt);
+err_free_slist:
+ kfree(pt->slist);
+ pt->slist = NULL;
+err_free_mem:
+ vfree(mem);
+err_null:
+ return NULL;
+}
+
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt)
+{
+ pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
+ saa7146_pgtable_free(pci, pt);
+ kfree(pt->slist);
+ pt->slist = NULL;
+ vfree(mem);
}
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -166,8 +183,6 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
return;
pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
pt->cpu = NULL;
- kfree(pt->slist);
- pt->slist = NULL;
}
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
@@ -528,6 +543,7 @@ EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
+EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
EXPORT_SYMBOL_GPL(saa7146_setgpio);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index c18a5da6493..b4770aecc01 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -307,7 +307,6 @@ static int fops_release(struct inode *inode, struct file *file)
return 0;
}
-int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
/*
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index a97c8f5e9a5..efd2b746815 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -2,24 +2,16 @@
# Multimedia device configuration
#
-menu "Digital Video Broadcasting Devices"
+source "drivers/media/dvb/dvb-core/Kconfig"
-config DVB
- bool "DVB For Linux"
- depends on NET && INET
+menuconfig DVB_CAPTURE_DRIVERS
+ bool "DVB/ATSC adapters"
+ depends on DVB_CORE
+ default y
---help---
- Support Digital Video Broadcasting hardware. Enable this if you
- own a DVB adapter and want to use it or if you compile Linux for
- a digital SetTopBox.
-
- API specs and user tools are available from <http://www.linuxtv.org/>.
+ Say Y to select Digital TV adapters
- Please report problems regarding this driver to the LinuxDVB
- mailing list.
-
- If unsure say N.
-
-source "drivers/media/dvb/dvb-core/Kconfig"
+if DVB_CAPTURE_DRIVERS
comment "Supported SAA7146 based PCI Adapters"
depends on DVB_CORE && PCI && I2C
@@ -48,4 +40,4 @@ comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
-endmenu
+endif # DVB_CAPTURE_DRIVERS
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
index 1990eda10c4..e3e6839f807 100644
--- a/drivers/media/dvb/dvb-core/Kconfig
+++ b/drivers/media/dvb/dvb-core/Kconfig
@@ -1,12 +1,22 @@
config DVB_CORE
- tristate "DVB Core Support"
- depends on DVB
+ tristate "DVB for Linux"
+ depends on NET && INET
select CRC32
help
+ Support Digital Video Broadcasting hardware. Enable this if you
+ own a DVB adapter and want to use it or if you compile Linux for
+ a digital SetTopBox.
+
DVB core utility functions for device handling, software fallbacks etc.
Say Y when you have a DVB card and want to use it. Say Y if your want
to build your drivers outside the kernel, but need the DVB core. All
in-kernel drivers will select this automatically if needed.
+
+ API specs and user tools are available from <http://www.linuxtv.org/>.
+
+ Please report problems regarding this driver to the LinuxDVB
+ mailing list.
+
If unsure say N.
config DVB_CORE_ATTACH
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 97715f7514d..403081689de 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -19,6 +19,7 @@
#define USB_VID_COMPRO_UNK 0x145f
#define USB_VID_CYPRESS 0x04b4
#define USB_VID_DIBCOM 0x10b8
+#define USB_VID_DPOSH 0x1498
#define USB_VID_DVICO 0x0fe9
#define USB_VID_EMPIA 0xeb1a
#define USB_VID_GENPIX 0x09c0
@@ -61,6 +62,8 @@
#define USB_PID_DIBCOM_STK7700P 0x1e14
#define USB_PID_DIBCOM_STK7700P_PC 0x1e78
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
+#define USB_PID_DPOSH_M9206_COLD 0x9206
+#define USB_PID_DPOSH_M9206_WARM 0xa090
#define USB_PID_UNIWILL_STK7700P 0x6003
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
@@ -145,6 +148,8 @@
#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
#define USB_PID_OPERA1_COLD 0x2830
#define USB_PID_OPERA1_WARM 0x3829
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514
+#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 0d721731a52..6f824a569e1 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -119,7 +119,7 @@ struct usb_data_stream_properties {
* @caps: capabilities of the DVB USB device.
* @pid_filter_count: number of PID filter position in the optional hardware
* PID-filter.
- * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
+ * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
* device (not URB submitting/killing).
* @pid_filter_ctrl: called to en/disable the PID filter, if any.
* @pid_filter: called to set/unset a PID for filtering.
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index 45d7bc214c1..c546ddeda5d 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -3,8 +3,8 @@
* Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
*
* 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.
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, version 2.
*
* see Documentation/dvb/README.dvb-usb for more information
*/
@@ -22,26 +22,7 @@ static int dvb_usb_m920x_debug;
module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
-static struct dvb_usb_rc_key megasky_rc_keys [] = {
- { 0x0, 0x12, KEY_POWER },
- { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
- { 0x0, 0x02, KEY_CHANNELUP },
- { 0x0, 0x05, KEY_CHANNELDOWN },
- { 0x0, 0x03, KEY_VOLUMEUP },
- { 0x0, 0x06, KEY_VOLUMEDOWN },
- { 0x0, 0x04, KEY_MUTE },
- { 0x0, 0x07, KEY_OK }, /* TS */
- { 0x0, 0x08, KEY_STOP },
- { 0x0, 0x09, KEY_MENU }, /* swap */
- { 0x0, 0x0a, KEY_REWIND },
- { 0x0, 0x1b, KEY_PAUSE },
- { 0x0, 0x1f, KEY_FASTFORWARD },
- { 0x0, 0x0c, KEY_RECORD },
- { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
- { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
-};
-
-static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\
+static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
u16 index, void *data, int size)
{
int ret;
@@ -55,14 +36,14 @@ static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\
}
if (ret != size) {
- deb_rc("m920x_read = no data\n");
+ deb("m920x_read = no data\n");
return -EIO;
}
return 0;
}
-static inline int m9206_write(struct usb_device *udev, u8 request,
+static inline int m920x_write(struct usb_device *udev, u8 request,
u16 value, u16 index)
{
int ret;
@@ -74,32 +55,40 @@ static inline int m9206_write(struct usb_device *udev, u8 request,
return ret;
}
-static int m9206_init(struct dvb_usb_device *d)
+static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
{
int ret = 0;
/* Remote controller init. */
if (d->props.rc_query) {
- if ((ret = m9206_write(d->udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0)
- return ret;
+ deb("Initialising remote control\n");
+ while (rc_seq->address) {
+ if ((ret = m920x_write(d->udev, M9206_CORE,
+ rc_seq->data,
+ rc_seq->address)) != 0) {
+ deb("Initialising remote control failed\n");
+ return ret;
+ }
- if ((ret = m9206_write(d->udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0)
- return ret;
+ rc_seq++;
+ }
+
+ deb("Initialising remote control success\n");
}
return ret;
}
-static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
- struct m9206_state *m = d->priv;
+ struct m920x_state *m = d->priv;
int i, ret = 0;
u8 rc_state[2];
- if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
+ if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
goto unlock;
- if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
+ if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
goto unlock;
for (i = 0; i < d->props.rc_key_map_size; i++)
@@ -111,6 +100,14 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
*state = REMOTE_NO_KEY_PRESSED;
goto unlock;
+ case 0x88: /* framing error or "invalid code" */
+ case 0x99:
+ case 0xc0:
+ case 0xd8:
+ *state = REMOTE_NO_KEY_PRESSED;
+ m->rep_count = 0;
+ goto unlock;
+
case 0x93:
case 0x92:
m->rep_count = 0;
@@ -118,31 +115,32 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
goto unlock;
case 0x91:
- /* For comfort. */
+ /* prevent immediate auto-repeat */
if (++m->rep_count > 2)
*state = REMOTE_KEY_REPEAT;
+ else
+ *state = REMOTE_NO_KEY_PRESSED;
goto unlock;
default:
- deb_rc("Unexpected rc response %x\n", rc_state[0]);
+ deb("Unexpected rc state %02x\n", rc_state[0]);
*state = REMOTE_NO_KEY_PRESSED;
goto unlock;
}
}
if (rc_state[1] != 0)
- deb_rc("Unknown rc key %x\n", rc_state[1]);
+ deb("Unknown rc key %02x\n", rc_state[1]);
*state = REMOTE_NO_KEY_PRESSED;
- unlock:
+ unlock:
return ret;
}
/* I2C */
-static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
- int num)
+static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i, j;
@@ -155,33 +153,40 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
return -EAGAIN;
for (i = 0; i < num; i++) {
- if (msg[i].flags & (I2C_M_NO_RD_ACK|I2C_M_IGNORE_NAK|I2C_M_TEN) ||
- msg[i].len == 0) {
- /* For a 0 byte message, I think sending the address to index 0x80|0x40
- * would be the correct thing to do. However, zero byte messages are
- * only used for probing, and since we don't know how to get the slave's
- * ack, we can't probe. */
+ if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
+ /* For a 0 byte message, I think sending the address
+ * to index 0x80|0x40 would be the correct thing to
+ * do. However, zero byte messages are only used for
+ * probing, and since we don't know how to get the
+ * slave's ack, we can't probe. */
ret = -ENOTSUPP;
goto unlock;
}
/* Send START & address/RW bit */
if (!(msg[i].flags & I2C_M_NOSTART)) {
- if ((ret = m9206_write(d->udev, M9206_I2C, (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), 0x80)) != 0)
+ if ((ret = m920x_write(d->udev, M9206_I2C,
+ (msg[i].addr << 1) |
+ (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
goto unlock;
/* Should check for ack here, if we knew how. */
}
if (msg[i].flags & I2C_M_RD) {
for (j = 0; j < msg[i].len; j++) {
- /* Last byte of transaction? Send STOP, otherwise send ACK. */
- int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x01;
- if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x20|stop, &msg[i].buf[j], 1)) != 0)
+ /* Last byte of transaction?
+ * Send STOP, otherwise send ACK. */
+ int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
+
+ if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
+ 0x20 | stop,
+ &msg[i].buf[j], 1)) != 0)
goto unlock;
}
} else {
for (j = 0; j < msg[i].len; j++) {
/* Last byte of transaction? Then send STOP. */
- int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x00;
- if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
+ int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
+
+ if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
goto unlock;
/* Should check for ack here too. */
}
@@ -189,25 +194,25 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
}
ret = num;
-unlock:
+ unlock:
mutex_unlock(&d->i2c_mutex);
return ret;
}
-static u32 m9206_i2c_func(struct i2c_adapter *adapter)
+static u32 m920x_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
}
-static struct i2c_algorithm m9206_i2c_algo = {
- .master_xfer = m9206_i2c_xfer,
- .functionality = m9206_i2c_func,
+static struct i2c_algorithm m920x_i2c_algo = {
+ .master_xfer = m920x_i2c_xfer,
+ .functionality = m920x_i2c_func,
};
-
-static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx,
- int pid)
+/* pid filter */
+static int m920x_set_filter(struct dvb_usb_adapter *adap,
+ int type, int idx, int pid)
{
int ret = 0;
@@ -216,18 +221,18 @@ static int m9206_set_filter(struct dvb_usb_adapter *adap, int type, int idx,
pid |= 0x8000;
- if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
+ if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
return ret;
- if ((ret = m9206_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
+ if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
return ret;
return ret;
}
-static int m9206_update_filters(struct dvb_usb_adapter *adap)
+static int m920x_update_filters(struct dvb_usb_adapter *adap)
{
- struct m9206_state *m = adap->dev->priv;
+ struct m920x_state *m = adap->dev->priv;
int enabled = m->filtering_enabled;
int i, ret = 0, filter = 0;
@@ -236,14 +241,14 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap)
enabled = 0;
/* Disable all filters */
- if ((ret = m9206_set_filter(adap, 0x81, 1, enabled)) != 0)
+ if ((ret = m920x_set_filter(adap, 0x81, 1, enabled)) != 0)
return ret;
for (i = 0; i < M9206_MAX_FILTERS; i++)
- if ((ret = m9206_set_filter(adap, 0x81, i + 2, 0)) != 0)
+ if ((ret = m920x_set_filter(adap, 0x81, i + 2, 0)) != 0)
return ret;
- if ((ret = m9206_set_filter(adap, 0x82, 0, 0x0)) != 0)
+ if ((ret = m920x_set_filter(adap, 0x82, 0, 0x0)) != 0)
return ret;
/* Set */
@@ -252,40 +257,38 @@ static int m9206_update_filters(struct dvb_usb_adapter *adap)
if (m->filters[i] == 0)
continue;
- if ((ret = m9206_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0)
+ if ((ret = m920x_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0)
return ret;
filter++;
}
}
- if ((ret = m9206_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
+ if ((ret = m920x_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
return ret;
return ret;
}
-static int m9206_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
- struct m9206_state *m = adap->dev->priv;
+ struct m920x_state *m = adap->dev->priv;
m->filtering_enabled = onoff ? 1 : 0;
- return m9206_update_filters(adap);
+ return m920x_update_filters(adap);
}
-static int m9206_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
- int onoff)
+static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
{
- struct m9206_state *m = adap->dev->priv;
+ struct m920x_state *m = adap->dev->priv;
m->filters[index] = onoff ? pid : 0;
- return m9206_update_filters(adap);
+ return m920x_update_filters(adap);
}
-static int m9206_firmware_download(struct usb_device *udev,
- const struct firmware *fw)
+static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
{
u16 value, index, size;
u8 read[4], *buff;
@@ -293,13 +296,13 @@ static int m9206_firmware_download(struct usb_device *udev,
buff = kmalloc(65536, GFP_KERNEL);
- if ((ret = m9206_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
+ if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
goto done;
- deb_rc("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
+ deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
- if ((ret = m9206_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
+ if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
goto done;
- deb_rc("%x\n", read[0]);
+ deb("%x\n", read[0]);
for (pass = 0; pass < 2; pass++) {
for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
@@ -317,11 +320,11 @@ static int m9206_firmware_download(struct usb_device *udev,
memcpy(buff, fw->data + i, size);
ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
- M9206_FW,
- USB_TYPE_VENDOR | USB_DIR_OUT,
- value, index, buff, size, 20);
+ M9206_FW,
+ USB_TYPE_VENDOR | USB_DIR_OUT,
+ value, index, buff, size, 20);
if (ret != size) {
- deb_rc("error while uploading fw!\n");
+ deb("error while uploading fw!\n");
ret = -EIO;
goto done;
}
@@ -330,7 +333,7 @@ static int m9206_firmware_download(struct usb_device *udev,
i += size;
}
if (i != fw->size) {
- deb_rc("bad firmware file!\n");
+ deb("bad firmware file!\n");
ret = -EINVAL;
goto done;
}
@@ -338,11 +341,11 @@ static int m9206_firmware_download(struct usb_device *udev,
msleep(36);
- /* m9206 will disconnect itself from the bus after this. */
- (void) m9206_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
- deb_rc("firmware uploaded!\n");
+ /* m920x will disconnect itself from the bus after this. */
+ (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
+ deb("firmware uploaded!\n");
- done:
+ done:
kfree(buff);
return ret;
@@ -362,7 +365,8 @@ static int m920x_identify_state(struct usb_device *udev,
return 0;
}
-static int megasky_mt352_demod_init(struct dvb_frontend *fe)
+/* demod configurations */
+static int m920x_mt352_demod_init(struct dvb_frontend *fe)
{
u8 config[] = { CONFIG, 0x3d };
u8 clock[] = { CLOCK_CTL, 0x30 };
@@ -382,74 +386,174 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe)
mt352_write(fe, unk1, ARRAY_SIZE(unk1));
mt352_write(fe, unk2, ARRAY_SIZE(unk2));
- deb_rc("Demod init!\n");
+ deb("Demod init!\n");
return 0;
}
-static struct mt352_config megasky_mt352_config = {
+static struct mt352_config m920x_mt352_config = {
.demod_address = 0x0f,
.no_tuner = 1,
- .demod_init = megasky_mt352_demod_init,
+ .demod_init = m920x_mt352_demod_init,
+};
+
+static struct tda1004x_config m920x_tda10046_08_config = {
+ .demod_address = 0x08,
+ .invert = 0,
+ .invert_oclk = 0,
+ .ts_mode = TDA10046_TS_SERIAL,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .if_freq = TDA10046_FREQ_045,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .gpio_config = TDA10046_GPTRI,
+ .request_firmware = NULL,
+};
+
+static struct tda1004x_config m920x_tda10046_0b_config = {
+ .demod_address = 0x0b,
+ .invert = 0,
+ .invert_oclk = 0,
+ .ts_mode = TDA10046_TS_SERIAL,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .if_freq = TDA10046_FREQ_045,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .gpio_config = TDA10046_GPTRI,
+ .request_firmware = NULL, /* uses firmware EEPROM */
+};
+
+/* tuner configurations */
+static struct qt1010_config m920x_qt1010_config = {
+ .i2c_address = 0x62
};
-static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap)
+/* Callbacks for DVB USB */
+static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
{
- deb_rc("megasky_frontend_attach!\n");
+ deb("%s\n",__FUNCTION__);
- if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL)
+ if ((adap->fe = dvb_attach(mt352_attach,
+ &m920x_mt352_config,
+ &adap->dev->i2c_adap)) == NULL)
return -EIO;
return 0;
}
-static struct qt1010_config megasky_qt1010_config = {
- .i2c_address = 0x62
-};
-
-static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
+static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
{
- if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap,
- &megasky_qt1010_config) == NULL)
- return -ENODEV;
+ deb("%s\n",__FUNCTION__);
+
+ if ((adap->fe = dvb_attach(tda10046_attach,
+ &m920x_tda10046_08_config,
+ &adap->dev->i2c_adap)) == NULL)
+ return -EIO;
return 0;
}
-static struct tda1004x_config digivox_tda10046_config = {
- .demod_address = 0x08,
- .invert = 0,
- .invert_oclk = 0,
- .ts_mode = TDA10046_TS_SERIAL,
- .xtal_freq = TDA10046_XTAL_16M,
- .if_freq = TDA10046_FREQ_045,
- .agc_config = TDA10046_AGC_TDA827X,
- .gpio_config = TDA10046_GPTRI,
- .request_firmware = NULL,
-};
-
-static int digivox_tda10046_frontend_attach(struct dvb_usb_adapter *adap)
+static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
{
- deb_rc("digivox_tda10046_frontend_attach!\n");
+ deb("%s\n",__FUNCTION__);
- if ((adap->fe = dvb_attach(tda10046_attach, &digivox_tda10046_config,
+ if ((adap->fe = dvb_attach(tda10046_attach,
+ &m920x_tda10046_0b_config,
&adap->dev->i2c_adap)) == NULL)
return -EIO;
return 0;
}
-static int digivox_tda8275_tuner_attach(struct dvb_usb_adapter *adap)
+static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
{
- if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap,
- NULL) == NULL)
+ deb("%s\n",__FUNCTION__);
+
+ if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
return -ENODEV;
+
return 0;
}
+static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ deb("%s\n",__FUNCTION__);
+
+ if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
+ return -ENODEV;
+
+ return 0;
+}
+
+static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ deb("%s\n",__FUNCTION__);
+
+ if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
+ return -ENODEV;
+
+ return 0;
+}
+
+/* device-specific initialization */
+static struct m920x_inits megasky_rc_init [] = {
+ { M9206_RC_INIT2, 0xa8 },
+ { M9206_RC_INIT1, 0x51 },
+ { } /* terminating entry */
+};
+
+static struct m920x_inits tvwalkertwin_rc_init [] = {
+ { M9206_RC_INIT2, 0x00 },
+ { M9206_RC_INIT1, 0xef },
+ { 0xff28, 0x00 },
+ { 0xff23, 0x00 },
+ { 0xff21, 0x30 },
+ { } /* terminating entry */
+};
+
+/* ir keymaps */
+static struct dvb_usb_rc_key megasky_rc_keys [] = {
+ { 0x0, 0x12, KEY_POWER },
+ { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
+ { 0x0, 0x02, KEY_CHANNELUP },
+ { 0x0, 0x05, KEY_CHANNELDOWN },
+ { 0x0, 0x03, KEY_VOLUMEUP },
+ { 0x0, 0x06, KEY_VOLUMEDOWN },
+ { 0x0, 0x04, KEY_MUTE },
+ { 0x0, 0x07, KEY_OK }, /* TS */
+ { 0x0, 0x08, KEY_STOP },
+ { 0x0, 0x09, KEY_MENU }, /* swap */
+ { 0x0, 0x0a, KEY_REWIND },
+ { 0x0, 0x1b, KEY_PAUSE },
+ { 0x0, 0x1f, KEY_FASTFORWARD },
+ { 0x0, 0x0c, KEY_RECORD },
+ { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
+ { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
+};
+
+static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
+ { 0x0, 0x01, KEY_ZOOM }, /* Full Screen */
+ { 0x0, 0x02, KEY_CAMERA }, /* snapshot */
+ { 0x0, 0x03, KEY_MUTE },
+ { 0x0, 0x04, KEY_REWIND },
+ { 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */
+ { 0x0, 0x06, KEY_FASTFORWARD },
+ { 0x0, 0x07, KEY_RECORD },
+ { 0x0, 0x08, KEY_STOP },
+ { 0x0, 0x09, KEY_TIME }, /* Timeshift */
+ { 0x0, 0x0c, KEY_COFFEE }, /* Recall */
+ { 0x0, 0x0e, KEY_CHANNELUP },
+ { 0x0, 0x12, KEY_POWER },
+ { 0x0, 0x15, KEY_MENU }, /* source */
+ { 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */
+ { 0x0, 0x1a, KEY_CHANNELDOWN },
+ { 0x0, 0x1b, KEY_VOLUMEDOWN },
+ { 0x0, 0x1e, KEY_VOLUMEUP },
+};
+
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties megasky_properties;
static struct dvb_usb_device_properties digivox_mini_ii_properties;
+static struct dvb_usb_device_properties tvwalkertwin_properties;
+static struct dvb_usb_device_properties dposh_properties;
static int m920x_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@@ -457,19 +561,57 @@ static int m920x_probe(struct usb_interface *intf,
struct dvb_usb_device *d;
struct usb_host_interface *alt;
int ret;
+ struct m920x_inits *rc_init_seq = NULL;
+ int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
- deb_rc("Probed!\n");
+ deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
- if (((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) ||
- ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, THIS_MODULE, &d)) == 0))
- goto found;
+ if (bInterfaceNumber == 0) {
+ /* Single-tuner device, or first interface on
+ * multi-tuner device
+ */
- return ret;
+ if ((ret = dvb_usb_device_init(intf, &megasky_properties,
+ THIS_MODULE, &d)) == 0) {
+ rc_init_seq = megasky_rc_init;
+ goto found;
+ }
+
+ if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
+ THIS_MODULE, &d)) == 0) {
+ /* No remote control, so no rc_init_seq */
+ goto found;
+ }
+
+ /* This configures both tuners on the TV Walker Twin */
+ if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
+ THIS_MODULE, &d)) == 0) {
+ rc_init_seq = tvwalkertwin_rc_init;
+ goto found;
+ }
+
+ if ((ret = dvb_usb_device_init(intf, &dposh_properties,
+ THIS_MODULE, &d)) == 0) {
+ /* Remote controller not supported yet. */
+ goto found;
+ }
+
+ return ret;
+ } else {
+ /* Another interface on a multi-tuner device */
-found:
+ /* The LifeView TV Walker Twin gets here, but struct
+ * tvwalkertwin_properties already configured both
+ * tuners, so there is nothing for us to do here
+ */
+
+ return -ENODEV;
+ }
+
+ found:
alt = usb_altnum_to_altsetting(intf, 1);
if (alt == NULL) {
- deb_rc("No alt found!\n");
+ deb("No alt found!\n");
return -ENODEV;
}
@@ -478,7 +620,7 @@ found:
if (ret < 0)
return ret;
- if ((ret = m9206_init(d)) != 0)
+ if ((ret = m920x_init(d, rc_init_seq)) != 0)
return ret;
return ret;
@@ -488,6 +630,12 @@ static struct usb_device_id m920x_table [] = {
{ USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
{ USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
USB_PID_MSI_DIGI_VOX_MINI_II) },
+ { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+ USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
+ { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+ USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
+ { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
+ { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, m920x_table);
@@ -497,14 +645,14 @@ static struct dvb_usb_device_properties megasky_properties = {
.usb_ctrl = DEVICE_SPECIFIC,
.firmware = "dvb-usb-megasky-02.fw",
- .download_firmware = m9206_firmware_download,
+ .download_firmware = m920x_firmware_download,
.rc_interval = 100,
.rc_key_map = megasky_rc_keys,
.rc_key_map_size = ARRAY_SIZE(megasky_rc_keys),
- .rc_query = m9206_rc_query,
+ .rc_query = m920x_rc_query,
- .size_of_priv = sizeof(struct m9206_state),
+ .size_of_priv = sizeof(struct m920x_state),
.identify_state = m920x_identify_state,
.num_adapters = 1,
@@ -513,11 +661,11 @@ static struct dvb_usb_device_properties megasky_properties = {
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 8,
- .pid_filter = m9206_pid_filter,
- .pid_filter_ctrl = m9206_pid_filter_ctrl,
+ .pid_filter = m920x_pid_filter,
+ .pid_filter_ctrl = m920x_pid_filter_ctrl,
- .frontend_attach = megasky_mt352_frontend_attach,
- .tuner_attach = megasky_qt1010_tuner_attach,
+ .frontend_attach = m920x_mt352_frontend_attach,
+ .tuner_attach = m920x_qt1010_tuner_attach,
.stream = {
.type = USB_BULK,
@@ -530,7 +678,7 @@ static struct dvb_usb_device_properties megasky_properties = {
}
},
}},
- .i2c_algo = &m9206_i2c_algo,
+ .i2c_algo = &m920x_i2c_algo,
.num_device_descs = 1,
.devices = {
@@ -546,22 +694,22 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
.usb_ctrl = DEVICE_SPECIFIC,
.firmware = "dvb-usb-digivox-02.fw",
- .download_firmware = m9206_firmware_download,
+ .download_firmware = m920x_firmware_download,
- .size_of_priv = sizeof(struct m9206_state),
+ .size_of_priv = sizeof(struct m920x_state),
.identify_state = m920x_identify_state,
.num_adapters = 1,
.adapter = {{
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
- DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
.pid_filter_count = 8,
- .pid_filter = m9206_pid_filter,
- .pid_filter_ctrl = m9206_pid_filter_ctrl,
+ .pid_filter = m920x_pid_filter,
+ .pid_filter_ctrl = m920x_pid_filter_ctrl,
- .frontend_attach = digivox_tda10046_frontend_attach,
- .tuner_attach = digivox_tda8275_tuner_attach,
+ .frontend_attach = m920x_tda10046_08_frontend_attach,
+ .tuner_attach = m920x_tda8275_60_tuner_attach,
.stream = {
.type = USB_BULK,
@@ -574,7 +722,7 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
}
},
}},
- .i2c_algo = &m9206_i2c_algo,
+ .i2c_algo = &m920x_i2c_algo,
.num_device_descs = 1,
.devices = {
@@ -585,6 +733,122 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = {
}
};
+/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
+ *
+ * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
+ * TDA10046 #0 is located at i2c address 0x08
+ * TDA10046 #1 is located at i2c address 0x0b (presently disabled - not yet working)
+ * TDA8275A #0 is located at i2c address 0x60
+ * TDA8275A #1 is located at i2c address 0x61 (presently disabled - not yet working)
+ */
+static struct dvb_usb_device_properties tvwalkertwin_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .firmware = "dvb-usb-tvwalkert.fw",
+ .download_firmware = m920x_firmware_download,
+
+ .rc_interval = 100,
+ .rc_key_map = tvwalkertwin_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(tvwalkertwin_rc_keys),
+ .rc_query = m920x_rc_query,
+
+ .size_of_priv = sizeof(struct m920x_state),
+
+ .identify_state = m920x_identify_state,
+ .num_adapters = 1,
+ .adapter = {{
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+ .pid_filter_count = 8,
+ .pid_filter = m920x_pid_filter,
+ .pid_filter_ctrl = m920x_pid_filter_ctrl,
+
+ .frontend_attach = m920x_tda10046_08_frontend_attach,
+ .tuner_attach = m920x_tda8275_60_tuner_attach,
+
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x81,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ }},{
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+ .pid_filter_count = 8,
+ .pid_filter = m920x_pid_filter,
+ .pid_filter_ctrl = m920x_pid_filter_ctrl,
+
+ .frontend_attach = m920x_tda10046_0b_frontend_attach,
+ .tuner_attach = m920x_tda8275_61_tuner_attach,
+
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ },
+ }},
+ .i2c_algo = &m920x_i2c_algo,
+
+ .num_device_descs = 1,
+ .devices = {
+ { .name = "LifeView TV Walker Twin DVB-T USB2.0",
+ .cold_ids = { &m920x_table[2], NULL },
+ .warm_ids = { &m920x_table[3], NULL },
+ },
+ }
+};
+
+static struct dvb_usb_device_properties dposh_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .firmware = "dvb-usb-dposh-01.fw",
+ .download_firmware = m920x_firmware_download,
+
+ .size_of_priv = sizeof(struct m920x_state),
+
+ .identify_state = m920x_identify_state,
+ .num_adapters = 1,
+ .adapter = {{
+ /* Hardware pid filters don't work with this device/firmware */
+
+ .frontend_attach = m920x_mt352_frontend_attach,
+ .tuner_attach = m920x_qt1010_tuner_attach,
+
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x81,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ },
+ }},
+ .i2c_algo = &m920x_i2c_algo,
+
+ .num_device_descs = 1,
+ .devices = {
+ { .name = "Dposh DVB-T USB2.0",
+ .cold_ids = { &m920x_table[4], NULL },
+ .warm_ids = { &m920x_table[5], NULL },
+ },
+ }
+};
+
static struct usb_driver m920x_driver = {
.name = "dvb_usb_m920x",
.probe = m920x_probe,
@@ -615,6 +879,11 @@ module_init (m920x_module_init);
module_exit (m920x_module_exit);
MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
-MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / Uli m920x");
+MODULE_DESCRIPTION("DVB Driver for ULI M920x");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h
index 7dd3db65c80..2c8942d0422 100644
--- a/drivers/media/dvb/dvb-usb/m920x.h
+++ b/drivers/media/dvb/dvb-usb/m920x.h
@@ -4,7 +4,7 @@
#define DVB_USB_LOG_PREFIX "m920x"
#include "dvb-usb.h"
-#define deb_rc(args...) dprintk(dvb_usb_m920x_debug,0x01,args)
+#define deb(args...) dprintk(dvb_usb_m920x_debug,0x01,args)
#define M9206_CORE 0x22
#define M9206_RC_STATE 0xff51
@@ -59,9 +59,18 @@ What any other bits might mean, or how to get the slave's ACK/NACK
response to a write, is unknown.
*/
-struct m9206_state {
+struct m920x_state {
u16 filters[M9206_MAX_FILTERS];
int filtering_enabled;
int rep_count;
};
+
+/* Initialisation data for the m920x
+ */
+
+struct m920x_inits {
+ u16 address;
+ u8 data;
+};
+
#endif
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index 3ecb2e0ce80..c3fdc7cd094 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -204,8 +204,8 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd *m)
{
- //struct vp702x_fe_state *st = fe->demodulator_priv;
- u8 cmd[8];//,ibuf[10];
+ struct vp702x_fe_state *st = fe->demodulator_priv;
+ u8 cmd[8],ibuf[10];
memset(cmd,0,8);
deb_fe("%s\n",__FUNCTION__);
@@ -218,12 +218,12 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
memcpy(&cmd[3], m->msg, m->msg_len);
cmd[7] = vp702x_chksum(cmd,0,7);
-// vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+ vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
-// if (ibuf[2] == 0 && ibuf[3] == 0)
-// deb_fe("diseqc cmd failed.\n");
-// else
-// deb_fe("diseqc cmd succeeded.\n");
+ if (ibuf[2] == 0 && ibuf[3] == 0)
+ deb_fe("diseqc cmd failed.\n");
+ else
+ deb_fe("diseqc cmd succeeded.\n");
return 0;
}
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 058df5c1003..08a2599ed74 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -293,12 +293,20 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
* but no packets have been transfered.
* [2] Sometimes (actually very often) NBPACKETS stays at zero
* although one packet has been transfered.
+ * [3] Sometimes (actually rarely), the card gets into an erroneous
+ * mode where it continuously generates interrupts, claiming it
+ * has recieved nbpackets>TS_DMA_PACKETS packets, but no packet
+ * has been transfered. Only a reset seems to solve this
*/
if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
unsigned int i = 0;
while (pluto->dma_buf[i] == 0x47)
i += 188;
nbpackets = i / 188;
+ if (i == 0) {
+ pluto_reset_ts(pluto, 1);
+ dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n");
+ }
}
dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 67becdd4db6..ef1108c0bf1 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1246,6 +1246,9 @@ static void vpeirq(unsigned long data)
if (!budget->feeding1 || (newdma == olddma))
return;
+ /* Ensure streamed PCI data is synced to CPU */
+ pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
#if 0
/* track rps1 activity */
printk("vpeirq: %02x Event Counter 1 0x%04x\n",
@@ -2679,8 +2682,8 @@ err_iobuf_vfree_6:
err_pci_free_5:
pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus);
err_saa71466_vfree_4:
- if (!av7110->grabbing)
- saa7146_pgtable_free(pdev, &av7110->pt);
+ if (av7110->grabbing)
+ saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt);
err_i2c_del_3:
i2c_del_adapter(&av7110->i2c_adap);
err_dvb_unregister_adapter_2:
@@ -2710,7 +2713,7 @@ static int __devexit av7110_detach(struct saa7146_dev* saa)
SAA7146_ISR_CLEAR(saa, MASK_10);
msleep(50);
tasklet_kill(&av7110->vpe_tasklet);
- saa7146_pgtable_free(saa->pci, &av7110->pt);
+ saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt);
}
av7110_exit_v4l(av7110);
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 4ed4599ce81..9d42f88ebb0 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -904,7 +904,7 @@ static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struc
band = 1;
} else if (tuner_frequency < 200000000) {
cp = 6;
- band = 2;
+ band = 1;
} else if (tuner_frequency < 290000000) {
cp = 3;
band = 2;
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 6b97dc1e6b6..2557ac9620d 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -195,6 +195,9 @@ static void vpeirq(unsigned long data)
u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
u32 count;
+ /* Ensure streamed PCI data is synced to CPU */
+ pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE);
+
/* nearest lower position divisible by 188 */
newdma -= newdma % 188;
@@ -504,16 +507,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
strcpy(budget->i2c_adap.name, budget->card->name);
if (i2c_add_adapter(&budget->i2c_adap) < 0) {
- dvb_unregister_adapter(&budget->dvb_adapter);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_dvb_unregister;
}
ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac);
- if (NULL ==
- (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt))) {
+ budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt);
+ if (NULL == budget->grabbing) {
ret = -ENOMEM;
- goto err;
+ goto err_del_i2c;
}
saa7146_write(dev, PCI_BT_V1, 0x001c0000);
@@ -526,14 +529,16 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
if (bi->type != BUDGET_FS_ACTIVY)
saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
- if (budget_register(budget) == 0) {
- return 0;
- }
-err:
- i2c_del_adapter(&budget->i2c_adap);
+ if (budget_register(budget) == 0)
+ return 0; /* Everything OK */
+
+ /* An error occurred, cleanup resources */
+ saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
- vfree(budget->grabbing);
+err_del_i2c:
+ i2c_del_adapter(&budget->i2c_adap);
+err_dvb_unregister:
dvb_unregister_adapter(&budget->dvb_adapter);
return ret;
@@ -555,15 +560,13 @@ int ttpci_budget_deinit(struct budget *budget)
budget_unregister(budget);
- i2c_del_adapter(&budget->i2c_adap);
-
- dvb_unregister_adapter(&budget->dvb_adapter);
-
tasklet_kill(&budget->vpe_tasklet);
- saa7146_pgtable_free(dev->pci, &budget->pt);
+ saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt);
- vfree(budget->grabbing);
+ i2c_del_adapter(&budget->i2c_adap);
+
+ dvb_unregister_adapter(&budget->dvb_adapter);
return 0;
}
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index af66a5d5ecd..a6ac82a609d 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -2,8 +2,14 @@
# Multimedia Video device configuration
#
-menu "Radio Adapters"
+menuconfig RADIO_ADAPTERS
+ bool "Radio Adapters"
depends on VIDEO_DEV
+ default y
+ ---help---
+ Say Y here to enable selecting AM/FM radio adapters.
+
+if RADIO_ADAPTERS
config RADIO_CADET
tristate "ADS Cadet AM/FM Tuner"
@@ -328,4 +334,5 @@ config USB_DSBR
To compile this driver as a module, choose M here: the
module will be called dsbr100.
-endmenu
+
+endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 449df1bb00d..3bd07f7e377 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -33,6 +33,10 @@
History:
+ Version 0.42:
+ Converted dsbr100 to use video_ioctl2
+ by Douglas Landgraf <dougsland@gmail.com>
+
Version 0.41-ac1:
Alan Cox: Some cleanups and fixes
@@ -121,8 +125,6 @@ devices, that would be 76 and 91. */
static int usb_dsbr100_probe(struct usb_interface *intf,
const struct usb_device_id *id);
static void usb_dsbr100_disconnect(struct usb_interface *intf);
-static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
static int usb_dsbr100_open(struct inode *inode, struct file *file);
static int usb_dsbr100_close(struct inode *inode, struct file *file);
@@ -142,26 +144,6 @@ struct dsbr100_device {
};
-/* File system interface */
-static const struct file_operations usb_dsbr100_fops = {
- .owner = THIS_MODULE,
- .open = usb_dsbr100_open,
- .release = usb_dsbr100_close,
- .ioctl = usb_dsbr100_ioctl,
- .compat_ioctl = v4l_compat_ioctl32,
- .llseek = no_llseek,
-};
-
-/* V4L interface */
-static struct video_device dsbr100_videodev_template=
-{
- .owner = THIS_MODULE,
- .name = "D-Link DSB-R 100",
- .type = VID_TYPE_TUNER,
- .fops = &usb_dsbr100_fops,
- .release = video_device_release,
-};
-
static struct usb_device_id usb_dsbr100_device_table [] = {
{ USB_DEVICE(DSB100_VENDOR, DSB100_PRODUCT) },
{ } /* Terminating entry */
@@ -252,37 +234,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
/* USB subsystem interface begins here */
-/* check if the device is present and register with v4l and
-usb if it is */
-static int usb_dsbr100_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct dsbr100_device *radio;
-
- if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
- return -ENOMEM;
- if (!(radio->videodev = video_device_alloc())) {
- kfree(radio);
- return -ENOMEM;
- }
- memcpy(radio->videodev, &dsbr100_videodev_template,
- sizeof(dsbr100_videodev_template));
- radio->removed = 0;
- radio->users = 0;
- radio->usbdev = interface_to_usbdev(intf);
- radio->curfreq = FREQ_MIN*FREQ_MUL;
- video_set_drvdata(radio->videodev, radio);
- if (video_register_device(radio->videodev, VFL_TYPE_RADIO,
- radio_nr)) {
- warn("Could not register video device");
- video_device_release(radio->videodev);
- kfree(radio);
- return -EIO;
- }
- usb_set_intfdata(intf, radio);
- return 0;
-}
-
/* handle unplugging of the device, release data structures
if nothing keeps us from doing it. If something is still
keeping us busy, the release callback of v4l will take care
@@ -307,133 +258,147 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
}
-/* Video for Linux interface */
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ strlcpy(v->driver, "dsbr100", sizeof(v->driver));
+ strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
+ sprintf(v->bus_info, "ISA");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
-static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
- struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
+ struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
+
+ if (v->index > 0)
+ return -EINVAL;
+
+ dsbr100_getstat(radio);
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = FREQ_MIN*FREQ_MUL;
+ v->rangehigh = FREQ_MAX*FREQ_MUL;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if(radio->stereo)
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ else
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff; /* We can't get the signal strength */
+ return 0;
+}
- if (!radio)
- return -EIO;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
- switch(cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *v = arg;
- memset(v,0,sizeof(*v));
- strlcpy(v->driver, "dsbr100", sizeof (v->driver));
- strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *v = arg;
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
- if (v->index > 0)
- return -EINVAL;
+ radio->curfreq = f->frequency;
+ if (dsbr100_setfreq(radio, radio->curfreq)==-1)
+ warn("Set frequency failed");
+ return 0;
+}
- dsbr100_getstat(radio);
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
- v->type = V4L2_TUNER_RADIO;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = radio->curfreq;
+ return 0;
+}
- v->rangelow = FREQ_MIN*FREQ_MUL;
- v->rangehigh = FREQ_MAX*FREQ_MUL;
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(radio->stereo)
- v->audmode = V4L2_TUNER_MODE_STEREO;
- else
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF; /* We can't get the signal strength */
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *v = arg;
-
- if (v->index > 0)
- return -EINVAL;
+ }
+ return -EINVAL;
+}
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
- radio->curfreq = f->frequency;
- if (dsbr100_setfreq(radio, radio->curfreq)==-1)
- warn("Set frequency failed");
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = radio->muted;
+ return 0;
+ }
+ return -EINVAL;
+}
- f->type = V4L2_TUNER_RADIO;
- f->frequency = radio->curfreq;
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct dsbr100_device *radio = video_get_drvdata(video_devdata(file));
- return 0;
- }
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
- }
- return -EINVAL;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=radio->muted;
- return 0;
- }
- return -EINVAL;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl= arg;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- if (dsbr100_stop(radio)==-1)
- warn("Radio did not respond properly");
- } else {
- if (dsbr100_start(radio)==-1)
- warn("Radio did not respond properly");
- }
- return 0;
- }
- return -EINVAL;
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value) {
+ if (dsbr100_stop(radio)==-1)
+ warn("Radio did not respond properly");
+ } else {
+ if (dsbr100_start(radio)==-1)
+ warn("Radio did not respond properly");
}
- default:
- return v4l_compat_translate_ioctl(inode,file,cmd,arg,
- usb_dsbr100_do_ioctl);
+ return 0;
}
+ return -EINVAL;
}
-static int usb_dsbr100_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- return video_usercopy(inode, file, cmd, arg, usb_dsbr100_do_ioctl);
+ if (a->index > 1)
+ return -EINVAL;
+
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static int usb_dsbr100_open(struct inode *inode, struct file *file)
@@ -465,6 +430,68 @@ static int usb_dsbr100_close(struct inode *inode, struct file *file)
return 0;
}
+/* File system interface */
+static const struct file_operations usb_dsbr100_fops = {
+ .owner = THIS_MODULE,
+ .open = usb_dsbr100_open,
+ .release = usb_dsbr100_close,
+ .ioctl = video_ioctl2,
+ .compat_ioctl = v4l_compat_ioctl32,
+ .llseek = no_llseek,
+};
+
+/* V4L2 interface */
+static struct video_device dsbr100_videodev_template =
+{
+ .owner = THIS_MODULE,
+ .name = "D-Link DSB-R 100",
+ .type = VID_TYPE_TUNER,
+ .fops = &usb_dsbr100_fops,
+ .release = video_device_release,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+};
+
+/* check if the device is present and register with v4l and
+usb if it is */
+static int usb_dsbr100_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct dsbr100_device *radio;
+
+ if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL)))
+ return -ENOMEM;
+ if (!(radio->videodev = video_device_alloc())) {
+ kfree(radio);
+ return -ENOMEM;
+ }
+ memcpy(radio->videodev, &dsbr100_videodev_template,
+ sizeof(dsbr100_videodev_template));
+ radio->removed = 0;
+ radio->users = 0;
+ radio->usbdev = interface_to_usbdev(intf);
+ radio->curfreq = FREQ_MIN*FREQ_MUL;
+ video_set_drvdata(radio->videodev, radio);
+ if (video_register_device(radio->videodev, VFL_TYPE_RADIO,radio_nr)) {
+ warn("Could not register video device");
+ video_device_release(radio->videodev);
+ kfree(radio);
+ return -EIO;
+ }
+ usb_set_intfdata(intf, radio);
+ return 0;
+}
+
static int __init dsbr100_init(void)
{
int retval = usb_register(&usb_dsbr100_driver);
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 8fbf0d8bd27..8cf2e9df5c8 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -48,6 +48,25 @@
#define CADET_VERSION KERNEL_VERSION(0,3,3)
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ },{
+ .id = V4L2_CID_AUDIO_VOLUME,
+ .name = "Volume",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0xff,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ }
+};
+
static int io=-1; /* default to isapnp activation */
static int radio_nr = -1;
static int users=0;
@@ -347,135 +366,165 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
}
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
+{
+ v->capabilities =
+ V4L2_CAP_TUNER |
+ V4L2_CAP_READWRITE;
+ v->version = CADET_VERSION;
+ strcpy(v->driver, "ADS Cadet");
+ strcpy(v->card, "ADS Cadet");
+ return 0;
+}
-static int cadet_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
- switch(cmd)
- {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
- memset(cap,0,sizeof(*cap));
- cap->capabilities =
- V4L2_CAP_TUNER |
- V4L2_CAP_READWRITE;
- cap->version = CADET_VERSION;
- strcpy(cap->driver, "ADS Cadet");
- strcpy(cap->card, "ADS Cadet");
- return 0;
+ v->type = V4L2_TUNER_RADIO;
+ switch (v->index) {
+ case 0:
+ strcpy(v->name, "FM");
+ v->capability = V4L2_TUNER_CAP_STEREO;
+ v->rangelow = 1400; /* 87.5 MHz */
+ v->rangehigh = 1728; /* 108.0 MHz */
+ v->rxsubchans=cadet_getstereo();
+ switch (v->rxsubchans){
+ case V4L2_TUNER_SUB_MONO:
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ break;
+ case V4L2_TUNER_SUB_STEREO:
+ v->audmode = V4L2_TUNER_MODE_STEREO;
+ break;
+ default: ;
}
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- memset(t,0,sizeof(*t));
- t->type = V4L2_TUNER_RADIO;
- switch (t->index)
- {
- case 0: strcpy(t->name, "FM");
- t->capability = V4L2_TUNER_CAP_STEREO;
- t->rangelow = 1400; /* 87.5 MHz */
- t->rangehigh = 1728; /* 108.0 MHz */
- t->rxsubchans=cadet_getstereo();
- switch (t->rxsubchans){
- case V4L2_TUNER_SUB_MONO:
- t->audmode = V4L2_TUNER_MODE_MONO;
- break;
- case V4L2_TUNER_SUB_STEREO:
- t->audmode = V4L2_TUNER_MODE_STEREO;
- break;
- default: ;
- }
- break;
- case 1: strcpy(t->name, "AM");
- t->capability = V4L2_TUNER_CAP_LOW;
- t->rangelow = 8320; /* 520 kHz */
- t->rangehigh = 26400; /* 1650 kHz */
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
- t->audmode = V4L2_TUNER_MODE_MONO;
- break;
- default:
- return -EINVAL;
- }
+ break;
+ case 1:
+ strcpy(v->name, "AM");
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->rangelow = 8320; /* 520 kHz */
+ v->rangehigh = 26400; /* 1650 kHz */
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ break;
+ default:
+ return -EINVAL;
+ }
+ v->signal = sigstrength; /* We might need to modify scaling of this */
+ return 0;
+}
- t->signal = sigstrength; /* We might need to modify scaling of this */
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
- if((t->index != 0)&&(t->index != 1))
- return -EINVAL;
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if((v->index != 0)&&(v->index != 1))
+ return -EINVAL;
+ curtuner = v->index;
+ return 0;
+}
- curtuner = t->index;
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- memset(f,0,sizeof(*f));
- f->tuner = curtuner;
- f->type = V4L2_TUNER_RADIO;
- f->frequency = cadet_getfreq();
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (f->type != V4L2_TUNER_RADIO){
- return -EINVAL;
- }
- if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) {
- return -EINVAL;
- }
- if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) {
- return -EINVAL;
- }
- cadet_setfreq(f->frequency);
- return 0;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *c = arg;
- switch (c->id){
- case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
- c->value = (cadet_getvol() == 0);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- c->value = cadet_getvol();
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *c = arg;
- switch (c->id){
- case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
- if (c->value) cadet_setvol(0);
- else cadet_setvol(0xffff);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- cadet_setvol(c->value);
- break;
- default:
- return -EINVAL;
- }
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ f->tuner = curtuner;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = cadet_getfreq();
+ return 0;
+}
+
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ if (f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+ if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728)))
+ return -EINVAL;
+ if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400)))
+ return -EINVAL;
+ cadet_setfreq(f->frequency);
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+ if (qc->id && qc->id == radio_qctrl[i].id) {
+ memcpy(qc, &(radio_qctrl[i]),
+ sizeof(*qc));
return 0;
}
+ }
+ return -EINVAL;
+}
- default:
- return -ENOIOCTLCMD;
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ switch (ctrl->id){
+ case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+ ctrl->value = (cadet_getvol() == 0);
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = cadet_getvol();
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
}
-static int
-cadet_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
{
- return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl);
+ switch (ctrl->id){
+ case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
+ if (ctrl->value)
+ cadet_setvol(0);
+ else
+ cadet_setvol(0xffff);
+ break;
+ case V4L2_CID_AUDIO_VOLUME:
+ cadet_setvol(ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index > 1)
+ return -EINVAL;
+ strcpy(a->name, "Radio");
+ a->capability = V4L2_AUDCAP_STEREO;
+ return 0;
+}
+
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ if (i != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ if (a->index != 0)
+ return -EINVAL;
+ return 0;
}
static int
@@ -512,7 +561,7 @@ static const struct file_operations cadet_fops = {
.open = cadet_open,
.release = cadet_release,
.read = cadet_read,
- .ioctl = cadet_ioctl,
+ .ioctl = video_ioctl2,
.poll = cadet_poll,
.compat_ioctl = v4l_compat_ioctl32,
.llseek = no_llseek,
@@ -524,6 +573,18 @@ static struct video_device cadet_radio=
.name = "Cadet radio",
.type = VID_TYPE_TUNER,
.fops = &cadet_fops,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
};
static struct pnp_device_id cadet_pnp_devices[] = {
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index 11f80cacd6e..8e33a19a22a 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -24,7 +24,6 @@
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
@@ -110,7 +109,6 @@ struct radio_device {
muted, /* VIDEO_AUDIO_MUTE */
stereo, /* VIDEO_TUNER_STEREO_ON */
tuned; /* signal strength (0 or 0xffff) */
- struct mutex lock;
};
static u32 radio_bits_get(struct radio_device *dev)
@@ -394,7 +392,6 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
}
radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
- mutex_init(&radio_unit->lock);
maestro_radio_inst = video_device_alloc();
if (maestro_radio_inst == NULL) {
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index a4715901512..203f4373eeb 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -410,7 +410,6 @@ static struct video_device zoltrix_radio =
.owner = THIS_MODULE,
.name = "Zoltrix Radio Plus",
.type = VID_TYPE_TUNER,
- .hardware = 0,
.fops = &zoltrix_fops,
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bc773781993..5cb3f54b548 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -2,14 +2,19 @@
# Multimedia Video device configuration
#
-menu "Video Capture Adapters"
+menuconfig VIDEO_CAPTURE_DRIVERS
+ bool "Video capture adapters"
depends on VIDEO_DEV
+ default y
+ ---help---
+ Say Y here to enable selecting the video adapters for
+ webcams, analog TV, and hybrid analog/digital TV.
+ Some of those devices also supports FM radio.
-comment "Video Capture Adapters"
+if VIDEO_CAPTURE_DRIVERS
config VIDEO_ADV_DEBUG
bool "Enable advanced debug functionality"
- depends on VIDEO_DEV
default n
---help---
Say Y here to enable advanced debugging functionality on some
@@ -34,7 +39,7 @@ config VIDEO_HELPER_CHIPS_AUTO
#
menu "Encoders/decoders and other helper chips"
- depends on VIDEO_DEV && !VIDEO_HELPER_CHIPS_AUTO
+ depends on !VIDEO_HELPER_CHIPS_AUTO
comment "Audio decoders"
@@ -61,7 +66,7 @@ config VIDEO_TDA7432
config VIDEO_TDA9840
tristate "Philips TDA9840 audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tda9840 audio decoder chip found on some Zoran boards.
@@ -79,7 +84,7 @@ config VIDEO_TDA9875
config VIDEO_TEA6415C
tristate "Philips TEA6415C audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tea6415c audio decoder chip found on some bt8xx boards.
@@ -88,7 +93,7 @@ config VIDEO_TEA6415C
config VIDEO_TEA6420
tristate "Philips TEA6420 audio processor"
- depends on VIDEO_DEV && I2C
+ depends on I2C
---help---
Support for tea6420 audio decoder chip found on some bt8xx boards.
@@ -469,7 +474,7 @@ config VIDEO_SAA5246A
config VIDEO_SAA5249
tristate "SAA5249 Teletext processor"
- depends on VIDEO_DEV && I2C && VIDEO_V4L2
+ depends on I2C && VIDEO_V4L2
help
Support for I2C bus based teletext using the SAA5249 chip. At the
moment this is only useful on some European WinTV cards.
@@ -479,7 +484,7 @@ config VIDEO_SAA5249
config TUNER_3036
tristate "SAB3036 tuner"
- depends on VIDEO_DEV && I2C && VIDEO_V4L1
+ depends on I2C && VIDEO_V4L1
help
Say Y here to include support for Philips SAB3036 compatible tuners.
If in doubt, say N.
@@ -681,8 +686,12 @@ config VIDEO_CAFE_CCIC
# USB Multimedia device configuration
#
-menu "V4L USB devices"
- depends on USB && VIDEO_DEV
+menuconfig V4L_USB_DRIVERS
+ bool "V4L USB devices"
+ depends on USB
+ default y
+
+if V4L_USB_DRIVERS
source "drivers/media/video/pvrusb2/Kconfig"
@@ -707,7 +716,7 @@ config VIDEO_OVCAMCHIP
config USB_W9968CF
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
- depends on USB && VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L1 && I2C
select VIDEO_OVCAMCHIP
---help---
Say Y here if you want support for cameras based on OV681 or
@@ -725,7 +734,7 @@ config USB_W9968CF
config USB_OV511
tristate "USB OV511 Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/ov511.txt>
@@ -736,7 +745,7 @@ config USB_OV511
config USB_SE401
tristate "USB SE401 Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/se401.txt>
@@ -749,7 +758,7 @@ source "drivers/media/video/sn9c102/Kconfig"
config USB_STV680
tristate "USB STV680 (Pencam) Camera support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. This includes the Pencam line of cameras.
@@ -765,7 +774,7 @@ source "drivers/media/video/pwc/Kconfig"
config USB_ZR364XX
tristate "USB ZR364XX Camera support"
- depends on USB && VIDEO_V4L2
+ depends on VIDEO_V4L2
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port.
@@ -775,6 +784,6 @@ config USB_ZR364XX
To compile this driver as a module, choose M here: the
module will be called zr364xx.
-endmenu # V4L USB devices
+endif # V4L_USB_DRIVERS
-endmenu
+endif # VIDEO_CAPTURE_DRIVERS
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 1757a588970..67bda9f9a44 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -555,7 +555,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
{
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+ int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
switch (fmt->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
@@ -567,7 +567,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
- Vlines = pix->height + (is_pal ? 4 : 7);
+ Vlines = pix->height + (is_50Hz ? 4 : 7);
if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 2ebde2fdbcb..543b05ebc0e 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -28,6 +28,7 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <asm/delay.h>
#include "cx88.h"
@@ -612,7 +613,7 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board
}
/* Driver asked for hardware access. */
-int cx8802_request_acquire(struct cx8802_driver *drv)
+static int cx8802_request_acquire(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
@@ -632,7 +633,7 @@ int cx8802_request_acquire(struct cx8802_driver *drv)
}
/* Driver asked to release hardware. */
-int cx8802_request_release(struct cx8802_driver *drv)
+static int cx8802_request_release(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index b94ef8ab28c..98fa35421bd 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -36,6 +36,7 @@
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/kthread.h>
+#include <linux/dma-mapping.h>
#include <asm/div64.h>
#include "cx88.h"
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
index 6068c9bf82c..82bc3a28aa2 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -111,10 +111,6 @@ static struct i2c_adapter vp3054_i2c_adap_template = {
.id = I2C_HW_B_CX2388x,
};
-static struct i2c_client vp3054_i2c_client_template = {
- .name = "VP-3054",
-};
-
int vp3054_i2c_probe(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
@@ -133,8 +129,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
sizeof(vp3054_i2c->adap));
memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
sizeof(vp3054_i2c->algo));
- memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template,
- sizeof(vp3054_i2c->client));
vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL;
@@ -144,7 +138,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
vp3054_i2c->algo.data = dev;
i2c_set_adapdata(&vp3054_i2c->adap, dev);
vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
- vp3054_i2c->client.adapter = &vp3054_i2c->adap;
vp3054_bit_setscl(dev,1);
vp3054_bit_setsda(dev,1);
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/video/cx88/cx88-vp3054-i2c.h
index b7a0a04d242..637a7d23223 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.h
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.h
@@ -26,7 +26,6 @@
struct vp3054_i2c_state {
struct i2c_adapter adap;
struct i2c_algo_bit_data algo;
- struct i2c_client client;
u32 state;
};
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 9285a58e47a..3823b62da4a 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_EM28XX
tristate "Empia EM2800/2820/2840 USB video capture support"
- depends on VIDEO_V4L1 && USB && I2C
+ depends on VIDEO_V4L1 && I2C
select VIDEO_BUF
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/drivers/media/video/et61x251/Kconfig b/drivers/media/video/et61x251/Kconfig
index c6bff705688..664676f4406 100644
--- a/drivers/media/video/et61x251/Kconfig
+++ b/drivers/media/video/et61x251/Kconfig
@@ -1,6 +1,6 @@
config USB_ET61X251
tristate "USB ET61X[12]51 PC Camera Controller support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on Etoms ET61X151
or ET61X251 PC Camera Controllers.
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 45b9328a538..e29f949adf5 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -74,7 +74,7 @@ int ivtv_first_minor = 0;
struct ivtv *ivtv_cards[IVTV_MAX_CARDS];
/* Protects ivtv_cards_active */
-spinlock_t ivtv_cards_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ivtv_cards_lock);
/* add your revision and whatnot here */
static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 1637097ddec..8976487a65f 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -804,7 +804,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
struct ivtv_open_id *item;
struct ivtv *itv = NULL;
struct ivtv_stream *s = NULL;
- int minor = MINOR(inode->i_rdev);
+ int minor = iminor(inode);
/* Find which card this open was on */
spin_lock(&ivtv_cards_lock);
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 5645c931889..d0c2cd78543 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_PVRUSB2
tristate "Hauppauge WinTV-PVR USB2 support"
- depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 5669c8ca9ca..20b614436d2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -391,22 +391,29 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
int pvr2_encoder_configure(struct pvr2_hdw *hdw)
{
int ret;
+ int val;
pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"
" (cx2341x module)");
hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING;
hdw->enc_ctl_state.width = hdw->res_hor_val;
hdw->enc_ctl_state.height = hdw->res_ver_val;
- hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur &
- (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ?
+ hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & V4L2_STD_525_60) ?
0 : 1);
ret = 0;
ret |= pvr2_encoder_prep_config(hdw);
+ /* saa7115: 0xf0 */
+ val = 0xf0;
+ if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ /* ivtv cx25840: 0x140 */
+ val = 0x140;
+ }
+
if (!ret) ret = pvr2_encoder_vcmd(
hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2,
- 0xf0, 0xf0);
+ val, val);
/* setup firmware to notify us about some events (don't know why...) */
if (!ret) ret = pvr2_encoder_vcmd(
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index acf651e01f9..1311891e7ee 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -83,7 +83,7 @@ static struct pvr2_string_table pvr2_client_lists[] = {
};
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
-static DECLARE_MUTEX(pvr2_unit_sem);
+static DEFINE_MUTEX(pvr2_unit_mtx);
static int ctlchg = 0;
static int initusbreset = 1;
@@ -2076,14 +2076,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
if (!hdw->ctl_read_urb) goto fail;
- down(&pvr2_unit_sem); do {
+ mutex_lock(&pvr2_unit_mtx); do {
for (idx = 0; idx < PVR_NUM; idx++) {
if (unit_pointers[idx]) continue;
hdw->unit_number = idx;
unit_pointers[idx] = hdw;
break;
}
- } while (0); up(&pvr2_unit_sem);
+ } while (0); mutex_unlock(&pvr2_unit_mtx);
cnt1 = 0;
cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2");
@@ -2186,13 +2186,13 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
}
pvr2_i2c_core_done(hdw);
pvr2_hdw_remove_usb_stuff(hdw);
- down(&pvr2_unit_sem); do {
+ mutex_lock(&pvr2_unit_mtx); do {
if ((hdw->unit_number >= 0) &&
(hdw->unit_number < PVR_NUM) &&
(unit_pointers[hdw->unit_number] == hdw)) {
unit_pointers[hdw->unit_number] = NULL;
}
- } while (0); up(&pvr2_unit_sem);
+ } while (0); mutex_unlock(&pvr2_unit_mtx);
kfree(hdw->controls);
kfree(hdw->mpeg_ctrl_info);
kfree(hdw->std_defs);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 58fc3c730fe..6786d3c0c98 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -23,6 +23,7 @@
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2.h"
#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
@@ -38,6 +39,10 @@ static unsigned int i2c_scan = 0;
module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
+static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
+module_param_array(ir_mode, int, NULL, 0444);
+MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
+
static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
unsigned int detail,
char *buf,unsigned int maxlen);
@@ -273,6 +278,15 @@ static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
}
+/* This is an entry point designed to always fail any attempt to perform a
+ transfer. We use this to cause certain I2C addresses to not be
+ probed. */
+static int i2c_black_hole(struct pvr2_hdw *hdw,
+ u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+ return -EIO;
+}
+
/* This is a special entry point that is entered if an I2C operation is
attempted to a cx25840 chip on model 24xxx hardware. This chip can
sometimes wedge itself. Worse still, when this happens msp3400 can
@@ -994,10 +1008,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
}
/* However, deal with various special cases for 24xxx hardware. */
+ if (ir_mode[hdw->unit_number] == 0) {
+ printk(KERN_INFO "%s: IR disabled\n",hdw->name);
+ hdw->i2c_func[0x18] = i2c_black_hole;
+ } else if (ir_mode[hdw->unit_number] == 1) {
+ if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
+ hdw->i2c_func[0x18] = i2c_24xxx_ir;
+ }
+ }
if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
hdw->i2c_func[0x1b] = i2c_hack_wm8775;
hdw->i2c_func[0x44] = i2c_hack_cx25840;
- hdw->i2c_func[0x18] = i2c_24xxx_ir;
}
// Configure the adapter and set up everything else related to it.
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index a741c556a39..7ab79baa1c8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -518,40 +518,32 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
}
sfp->item_last = cip;
- cip->attr_name.attr.owner = THIS_MODULE;
cip->attr_name.attr.name = "name";
cip->attr_name.attr.mode = S_IRUGO;
cip->attr_name.show = fp->show_name;
- cip->attr_type.attr.owner = THIS_MODULE;
cip->attr_type.attr.name = "type";
cip->attr_type.attr.mode = S_IRUGO;
cip->attr_type.show = fp->show_type;
- cip->attr_min.attr.owner = THIS_MODULE;
cip->attr_min.attr.name = "min_val";
cip->attr_min.attr.mode = S_IRUGO;
cip->attr_min.show = fp->show_min;
- cip->attr_max.attr.owner = THIS_MODULE;
cip->attr_max.attr.name = "max_val";
cip->attr_max.attr.mode = S_IRUGO;
cip->attr_max.show = fp->show_max;
- cip->attr_val.attr.owner = THIS_MODULE;
cip->attr_val.attr.name = "cur_val";
cip->attr_val.attr.mode = S_IRUGO;
- cip->attr_custom.attr.owner = THIS_MODULE;
cip->attr_custom.attr.name = "custom_val";
cip->attr_custom.attr.mode = S_IRUGO;
- cip->attr_enum.attr.owner = THIS_MODULE;
cip->attr_enum.attr.name = "enum_val";
cip->attr_enum.attr.mode = S_IRUGO;
cip->attr_enum.show = fp->show_enum;
- cip->attr_bits.attr.owner = THIS_MODULE;
cip->attr_bits.attr.name = "bit_val";
cip->attr_bits.attr.mode = S_IRUGO;
cip->attr_bits.show = fp->show_bits;
@@ -616,12 +608,10 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
dip = kzalloc(sizeof(*dip),GFP_KERNEL);
if (!dip) return;
- dip->attr_debugcmd.attr.owner = THIS_MODULE;
dip->attr_debugcmd.attr.name = "debugcmd";
dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
dip->attr_debugcmd.show = debugcmd_show;
dip->attr_debugcmd.store = debugcmd_store;
- dip->attr_debuginfo.attr.owner = THIS_MODULE;
dip->attr_debuginfo.attr.name = "debuginfo";
dip->attr_debuginfo.attr.mode = S_IRUGO;
dip->attr_debuginfo.show = debuginfo_show;
@@ -811,7 +801,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
return;
}
- sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE;
sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -825,7 +814,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_minor_number_created_ok = !0;
}
- sfp->attr_v4l_radio_minor_number.attr.owner = THIS_MODULE;
sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -839,7 +827,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_radio_minor_number_created_ok = !0;
}
- sfp->attr_unit_number.attr.owner = THIS_MODULE;
sfp->attr_unit_number.attr.name = "unit_number";
sfp->attr_unit_number.attr.mode = S_IRUGO;
sfp->attr_unit_number.show = unit_number_show;
@@ -852,7 +839,6 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->unit_number_created_ok = !0;
}
- sfp->attr_bus_info.attr.owner = THIS_MODULE;
sfp->attr_bus_info.attr.name = "bus_info_str";
sfp->attr_bus_info.attr.mode = S_IRUGO;
sfp->attr_bus_info.show = bus_info_show;
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 8fdf7101d3b..7298cf2e165 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -1,6 +1,6 @@
config USB_PWC
tristate "USB Philips Cameras"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y or M here if you want to use one of these Philips & OEM
webcams:
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 4ea479baee7..50f15adfa7c 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1170,6 +1170,42 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
},
},
+ [SAA7134_BOARD_ECS_TVP3XP_4CB6] = {
+ /* Barry Scott <barry.scott@onelan.co.uk> */
+ .name = "Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM)",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_PHILIPS_PAL_I,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_tv_mono,
+ .vmux = 1,
+ .amux = LINE2,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ },{
+ .name = "CVid over SVid",
+ .vmux = 0,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ },
[SAA7134_BOARD_AVACSSMARTTV] = {
/* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
.name = "AVACS SmartTV",
@@ -2754,6 +2790,35 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
},
},
+ [SAA7134_BOARD_KWORLD_DVBT_210] = {
+ .name = "KWorld DVB-T 210",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .gpiomask = 1 << 21,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
+ },
+ },
[SAA7134_BOARD_KWORLD_ATSC110] = {
.name = "Kworld ATSC110",
.audio_clock = 0x00187de7,
@@ -3407,6 +3472,36 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x0200000,
},
},
+ [SAA7134_BOARD_SABRENT_TV_PCB05] = {
+ .name = "Sabrent PCMCIA TV-PCB05",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_comp2,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ .mute = {
+ .name = name_mute,
+ .amux = TV,
+ },
+ },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -3515,7 +3610,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x0214, /* Standard PCI, LR214WF */
+ .subdevice = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x5168, /* Animation Technologies (LifeView) */
+ .subdevice = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -3689,6 +3790,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1019,
+ .subdevice = 0x4cb6,
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB6,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x12ab,
.subdevice = 0x0800,
@@ -3915,6 +4022,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_TEVION_DVBT_220RF,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x17de,
+ .subdevice = 0x7250,
+ .driver_data = SAA7134_BOARD_KWORLD_DVBT_210,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
.subvendor = 0x17de,
.subdevice = 0x7350,
@@ -4100,6 +4213,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x4857,
.driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
},{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */
+ .subdevice = 0x2003, /* OEM cardbus */
+ .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05,
+ },{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -4178,6 +4297,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_CINERGY600_MK3:
case SAA7134_BOARD_ECS_TVP3XP:
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
+ case SAA7134_BOARD_ECS_TVP3XP_4CB6:
case SAA7134_BOARD_MD2819:
case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
case SAA7134_BOARD_KWORLD_XPERT:
@@ -4426,6 +4546,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_PINNACLE_PCTV_310i:
+ case SAA7134_BOARD_KWORLD_DVBT_210:
case SAA7134_BOARD_TEVION_DVBT_220RF:
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 65aec881bbd..e0eec80088c 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -887,6 +887,20 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = {
.antenna_switch= 2,
.request_firmware = philips_tda1004x_request_firmware
};
+static struct tda1004x_config kworld_dvb_t_210_config = {
+ .demod_address = 0x08,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_16M,
+ .agc_config = TDA10046_AGC_TDA827X,
+ .gpio_config = TDA10046_GP11_I,
+ .if_freq = TDA10046_FREQ_045,
+ .i2c_gate = 0x4b,
+ .tuner_address = 0x61,
+ .tuner_config = 2,
+ .antenna_switch= 1,
+ .request_firmware = philips_tda1004x_request_firmware
+};
/* ------------------------------------------------------------------
* special case: this card uses saa713x GPIO22 for the mode switch
*/
@@ -1039,6 +1053,9 @@ static int dvb_init(struct saa7134_dev *dev)
dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
}
break;
+ case SAA7134_BOARD_KWORLD_DVBT_210:
+ configure_tda827x_fe(dev, &kworld_dvb_t_210_config);
+ break;
case SAA7134_BOARD_PHILIPS_TIGER:
configure_tda827x_fe(dev, &philips_tiger_config);
break;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 62224cc958f..15623b27ad2 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -235,6 +235,9 @@ struct saa7134_format {
#define SAA7134_BOARD_AVERMEDIA_M102 110
#define SAA7134_BOARD_ASUS_P7131_4871 111
#define SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA 112
+#define SAA7134_BOARD_ECS_TVP3XP_4CB6 113
+#define SAA7134_BOARD_KWORLD_DVBT_210 114
+#define SAA7134_BOARD_SABRENT_TV_PCB05 115
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/sn9c102/Kconfig b/drivers/media/video/sn9c102/Kconfig
index 19204f5686e..f71f272776d 100644
--- a/drivers/media/video/sn9c102/Kconfig
+++ b/drivers/media/video/sn9c102/Kconfig
@@ -1,6 +1,6 @@
config USB_SN9C102
tristate "USB SN9C1xx PC Camera Controller support"
- depends on USB && VIDEO_V4L2
+ depends on VIDEO_V4L2
---help---
Say Y here if you want support for cameras based on SONiX SN9C101,
SN9C102, SN9C103, SN9C105 and SN9C120 PC Camera Controllers.
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h
index 680e7463452..11fcb49f5b9 100644
--- a/drivers/media/video/sn9c102/sn9c102.h
+++ b/drivers/media/video/sn9c102/sn9c102.h
@@ -141,7 +141,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id)
void
sn9c102_attach_sensor(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor));
}
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 89f83354de3..74a204f8ebc 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -48,8 +48,8 @@
#define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia"
#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
#define SN9C102_MODULE_LICENSE "GPL"
-#define SN9C102_MODULE_VERSION "1:1.39"
-#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 39)
+#define SN9C102_MODULE_VERSION "1:1.44"
+#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 44)
/*****************************************************************************/
@@ -209,38 +209,41 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam)
}
/*****************************************************************************/
+
/*
- * Write a sequence of count value/register pairs. Returns -1 after the
- * first failed write, or 0 for no errors.
- */
+ Write a sequence of count value/register pairs. Returns -1 after the first
+ failed write, or 0 for no errors.
+*/
int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2],
int count)
{
struct usb_device* udev = cam->usbdev;
- u8* value = cam->control_buffer; /* Needed for DMA'able memory */
+ u8* buff = cam->control_buffer;
int i, res;
for (i = 0; i < count; i++) {
u8 index = valreg[i][1];
/*
- * index is a u8, so it must be <256 and can't be out of range.
- * If we put in a check anyway, gcc annoys us with a warning
- * that our check is useless. People get all uppity when they
- * see warnings in the kernel compile.
- */
-
- *value = valreg[i][0];
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x08, 0x41, index, 0,
- value, 1, SN9C102_CTRL_TIMEOUT);
+ index is a u8, so it must be <256 and can't be out of range.
+ If we put in a check anyway, gcc annoys us with a warning
+ hat our check is useless. People get all uppity when they
+ see warnings in the kernel compile.
+ */
+
+ *buff = valreg[i][0];
+
+ res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x08,
+ 0x41, index, 0, buff, 1,
+ SN9C102_CTRL_TIMEOUT);
+
if (res < 0) {
DBG(3, "Failed to write a register (value 0x%02X, "
- "index 0x%02X, error %d)", *value, index, res);
+ "index 0x%02X, error %d)", *buff, index, res);
return -1;
}
- cam->reg[index] = *value;
+ cam->reg[index] = *buff;
}
return 0;
@@ -272,8 +275,8 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index)
}
-/* NOTE: reading some registers always returns 0 */
-static int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
+/* NOTE: with the SN9C10[123] reading some registers always returns 0 */
+int sn9c102_read_reg(struct sn9c102_device* cam, u16 index)
{
struct usb_device* udev = cam->usbdev;
u8* buff = cam->control_buffer;
@@ -299,7 +302,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index)
static int
-sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
+sn9c102_i2c_wait(struct sn9c102_device* cam,
+ const struct sn9c102_sensor* sensor)
{
int i, r;
@@ -320,7 +324,7 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, struct sn9c102_sensor* sensor)
static int
sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
int r , err = 0;
@@ -342,7 +346,7 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam,
static int
sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor)
+ const struct sn9c102_sensor* sensor)
{
int r;
r = sn9c102_read_reg(cam, 0x08);
@@ -352,12 +356,12 @@ sn9c102_i2c_detect_write_error(struct sn9c102_device* cam,
int
sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 data0, u8 data1,
- u8 n, u8 buffer[])
+ const struct sn9c102_sensor* sensor, u8 data0,
+ u8 data1, u8 n, u8 buffer[])
{
struct usb_device* udev = cam->usbdev;
u8* data = cam->control_buffer;
- int err = 0, res;
+ int i = 0, err = 0, res;
/* Write cycle */
data[0] = ((sensor->interface == SN9C102_I2C_2WIRES) ? 0x80 : 0) |
@@ -402,7 +406,8 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
}
if (buffer)
- memcpy(buffer, data, sizeof(buffer));
+ for (i = 0; i < n && i < 5; i++)
+ buffer[n-i-1] = data[4-i];
return (int)data[4];
}
@@ -410,7 +415,7 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
int
sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 n, u8 data0,
+ const struct sn9c102_sensor* sensor, u8 n, u8 data0,
u8 data1, u8 data2, u8 data3, u8 data4, u8 data5)
{
struct usb_device* udev = cam->usbdev;
@@ -449,7 +454,7 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
int
sn9c102_i2c_try_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 address)
+ const struct sn9c102_sensor* sensor, u8 address)
{
return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id,
address, 1, NULL);
@@ -458,7 +463,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam,
int
sn9c102_i2c_try_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 address, u8 value)
+ const struct sn9c102_sensor* sensor, u8 address, u8 value)
{
return sn9c102_i2c_try_raw_write(cam, sensor, 3,
sensor->i2c_slave_id, address,
@@ -657,16 +662,6 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
}
-static void
-sn9c102_write_eoimarker(struct sn9c102_device* cam, struct sn9c102_frame_t* f)
-{
- static const u8 eoi_marker[2] = {0xff, 0xd9};
-
- memcpy(f->bufmem + f->buf.bytesused, eoi_marker, sizeof(eoi_marker));
- f->buf.bytesused += sizeof(eoi_marker);
-}
-
-
static void sn9c102_urb_complete(struct urb *urb)
{
struct sn9c102_device* cam = urb->context;
@@ -3181,14 +3176,14 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
static const struct file_operations sn9c102_fops = {
.owner = THIS_MODULE,
- .open = sn9c102_open,
+ .open = sn9c102_open,
.release = sn9c102_release,
- .ioctl = sn9c102_ioctl,
+ .ioctl = sn9c102_ioctl,
.compat_ioctl = v4l_compat_ioctl32,
- .read = sn9c102_read,
- .poll = sn9c102_poll,
- .mmap = sn9c102_mmap,
- .llseek = no_llseek,
+ .read = sn9c102_read,
+ .poll = sn9c102_poll,
+ .mmap = sn9c102_mmap,
+ .llseek = no_llseek,
};
/*****************************************************************************/
@@ -3251,7 +3246,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
break;
}
- for (i = 0; sn9c102_sensor_table[i]; i++) {
+ for (i = 0; i < ARRAY_SIZE(sn9c102_sensor_table); i++) {
err = sn9c102_sensor_table[i](cam);
if (!err)
break;
@@ -3262,7 +3257,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
DBG(3, "Support for %s maintained by %s",
cam->sensor.name, cam->sensor.maintainer);
} else {
- DBG(1, "No supported image sensor detected");
+ DBG(1, "No supported image sensor detected for this bridge");
err = -ENODEV;
goto fail;
}
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index f49bd8c5b86..916054faf9b 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -86,6 +86,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), },
/* SN9C105 */
+ { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
+ { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
@@ -100,6 +102,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), },
/* SN9C120 */
+ { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), },
{ SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), },
@@ -148,7 +151,6 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = {
&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */
&sn9c102_probe_tas5110d, /* detection based on USB pid/vid */
&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */
- NULL,
};
#endif /* _SN9C102_DEVTABLE_H_ */
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131d.c b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
index 28a861aed04..eaf9ad0dc8a 100644
--- a/drivers/media/video/sn9c102/sn9c102_hv7131d.c
+++ b/drivers/media/video/sn9c102/sn9c102_hv7131d.c
@@ -144,7 +144,7 @@ static int hv7131d_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor hv7131d = {
+static const struct sn9c102_sensor hv7131d = {
.name = "HV7131D",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -248,12 +248,10 @@ int sn9c102_probe_hv7131d(struct sn9c102_device* cam)
err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
{0x28, 0x17});
- if (err)
- return -EIO;
r0 = sn9c102_i2c_try_read(cam, &hv7131d, 0x00);
r1 = sn9c102_i2c_try_read(cam, &hv7131d, 0x01);
- if (r0 < 0 || r1 < 0)
+ if (err || r0 < 0 || r1 < 0)
return -EIO;
if (r0 != 0x00 || r1 != 0x04)
diff --git a/drivers/media/video/sn9c102/sn9c102_hv7131r.c b/drivers/media/video/sn9c102/sn9c102_hv7131r.c
index 5a495baa5f9..0fc401223cf 100644
--- a/drivers/media/video/sn9c102/sn9c102_hv7131r.c
+++ b/drivers/media/video/sn9c102/sn9c102_hv7131r.c
@@ -44,7 +44,6 @@ static int hv7131r_init(struct sn9c102_device* cam)
{0xb0, 0x2b}, {0xc0, 0x2c},
{0xd0, 0x2d}, {0xe0, 0x2e},
{0xf0, 0x2f}, {0xff, 0x30});
-
break;
case BRIDGE_SN9C105:
case BRIDGE_SN9C120:
@@ -254,7 +253,7 @@ static int hv7131r_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor hv7131r = {
+static const struct sn9c102_sensor hv7131r = {
.name = "HV7131R",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -350,11 +349,8 @@ int sn9c102_probe_hv7131r(struct sn9c102_device* cam)
{0x34, 0x01}, {0x20, 0x17},
{0x34, 0x01}, {0x46, 0x01});
- if (err)
- return -EIO;
-
devid = sn9c102_i2c_try_read(cam, &hv7131r, 0x00);
- if (devid < 0)
+ if (err || devid < 0)
return -EIO;
if (devid != 0x02)
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0343.c b/drivers/media/video/sn9c102/sn9c102_mi0343.c
index 9200845d011..00b134ca0a3 100644
--- a/drivers/media/video/sn9c102/sn9c102_mi0343.c
+++ b/drivers/media/video/sn9c102/sn9c102_mi0343.c
@@ -55,45 +55,45 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
struct v4l2_control* ctrl)
{
struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- u8 data[5+1];
+ u8 data[2];
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[2];
+ ctrl->value = data[0];
return 0;
case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+ data) < 0)
return -EIO;
break;
case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3] & 0x20 ? 1 : 0;
+ ctrl->value = data[1] & 0x20 ? 1 : 0;
return 0;
case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3] & 0x80 ? 1 : 0;
+ ctrl->value = data[1] & 0x80 ? 1 : 0;
return 0;
case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+ data) < 0)
return -EIO;
break;
case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+ data) < 0)
return -EIO;
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+ data) < 0)
return -EIO;
break;
default:
@@ -105,7 +105,7 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam,
case V4L2_CID_RED_BALANCE:
case V4L2_CID_BLUE_BALANCE:
case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = data[3] | (data[2] << 8);
+ ctrl->value = data[1] | (data[0] << 8);
if (ctrl->value >= 0x10 && ctrl->value <= 0x3f)
ctrl->value -= 0x10;
else if (ctrl->value >= 0x60 && ctrl->value <= 0x7f)
@@ -223,7 +223,7 @@ static int mi0343_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor mi0343 = {
+static const struct sn9c102_sensor mi0343 = {
.name = "MI-0343",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -332,20 +332,17 @@ static struct sn9c102_sensor mi0343 = {
int sn9c102_probe_mi0343(struct sn9c102_device* cam)
{
- u8 data[5+1];
- int err = 0;
-
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
+ u8 data[2];
- if (err)
+ if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
return -EIO;
if (sn9c102_i2c_try_raw_read(cam, &mi0343, mi0343.i2c_slave_id, 0x00,
2, data) < 0)
return -EIO;
- if (data[4] != 0x32 || data[3] != 0xe3)
+ if (data[1] != 0x42 || data[0] != 0xe3)
return -ENODEV;
sn9c102_attach_sensor(cam, &mi0343);
diff --git a/drivers/media/video/sn9c102/sn9c102_mi0360.c b/drivers/media/video/sn9c102/sn9c102_mi0360.c
index 64698acb0b1..f8d81d82e8d 100644
--- a/drivers/media/video/sn9c102/sn9c102_mi0360.c
+++ b/drivers/media/video/sn9c102/sn9c102_mi0360.c
@@ -27,20 +27,105 @@ static int mi0360_init(struct sn9c102_device* cam)
struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
- err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
- {0x0a, 0x14}, {0x40, 0x01},
- {0x20, 0x17}, {0x07, 0x18},
- {0xa0, 0x19}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x0a, 0x14}, {0x40, 0x01},
+ {0x20, 0x17}, {0x07, 0x18},
+ {0xa0, 0x19}, {0x02, 0x1c},
+ {0x03, 0x1d}, {0x0f, 0x1e},
+ {0x0c, 0x1f}, {0x00, 0x20},
+ {0x10, 0x21}, {0x20, 0x22},
+ {0x30, 0x23}, {0x40, 0x24},
+ {0x50, 0x25}, {0x60, 0x26},
+ {0x70, 0x27}, {0x80, 0x28},
+ {0x90, 0x29}, {0xa0, 0x2a},
+ {0xb0, 0x2b}, {0xc0, 0x2c},
+ {0xd0, 0x2d}, {0xe0, 0x2e},
+ {0xf0, 0x2f}, {0xff, 0x30});
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ err = sn9c102_write_const_regs(cam, {0x44, 0x01}, {0x40, 0x02},
+ {0x00, 0x03}, {0x1a, 0x04},
+ {0x50, 0x05}, {0x20, 0x06},
+ {0x10, 0x07}, {0x03, 0x10},
+ {0x08, 0x14}, {0xa2, 0x17},
+ {0x47, 0x18}, {0x00, 0x19},
+ {0x1d, 0x1a}, {0x10, 0x1b},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x29, 0x21},
+ {0x40, 0x22}, {0x54, 0x23},
+ {0x66, 0x24}, {0x76, 0x25},
+ {0x85, 0x26}, {0x94, 0x27},
+ {0xa1, 0x28}, {0xae, 0x29},
+ {0xbb, 0x2a}, {0xc7, 0x2b},
+ {0xd3, 0x2c}, {0xde, 0x2d},
+ {0xea, 0x2e}, {0xf4, 0x2f},
+ {0xff, 0x30}, {0x00, 0x3F},
+ {0xC7, 0x40}, {0x01, 0x41},
+ {0x44, 0x42}, {0x00, 0x43},
+ {0x44, 0x44}, {0x00, 0x45},
+ {0x44, 0x46}, {0x00, 0x47},
+ {0xC7, 0x48}, {0x01, 0x49},
+ {0xC7, 0x4A}, {0x01, 0x4B},
+ {0xC7, 0x4C}, {0x01, 0x4D},
+ {0x44, 0x4E}, {0x00, 0x4F},
+ {0x44, 0x50}, {0x00, 0x51},
+ {0x44, 0x52}, {0x00, 0x53},
+ {0xC7, 0x54}, {0x01, 0x55},
+ {0xC7, 0x56}, {0x01, 0x57},
+ {0xC7, 0x58}, {0x01, 0x59},
+ {0x44, 0x5A}, {0x00, 0x5B},
+ {0x44, 0x5C}, {0x00, 0x5D},
+ {0x44, 0x5E}, {0x00, 0x5F},
+ {0xC7, 0x60}, {0x01, 0x61},
+ {0xC7, 0x62}, {0x01, 0x63},
+ {0xC7, 0x64}, {0x01, 0x65},
+ {0x44, 0x66}, {0x00, 0x67},
+ {0x44, 0x68}, {0x00, 0x69},
+ {0x44, 0x6A}, {0x00, 0x6B},
+ {0xC7, 0x6C}, {0x01, 0x6D},
+ {0xC7, 0x6E}, {0x01, 0x6F},
+ {0xC7, 0x70}, {0x01, 0x71},
+ {0x44, 0x72}, {0x00, 0x73},
+ {0x44, 0x74}, {0x00, 0x75},
+ {0x44, 0x76}, {0x00, 0x77},
+ {0xC7, 0x78}, {0x01, 0x79},
+ {0xC7, 0x7A}, {0x01, 0x7B},
+ {0xC7, 0x7C}, {0x01, 0x7D},
+ {0x44, 0x7E}, {0x00, 0x7F},
+ {0x14, 0x84}, {0x00, 0x85},
+ {0x27, 0x86}, {0x00, 0x87},
+ {0x07, 0x88}, {0x00, 0x89},
+ {0xEC, 0x8A}, {0x0f, 0x8B},
+ {0xD8, 0x8C}, {0x0f, 0x8D},
+ {0x3D, 0x8E}, {0x00, 0x8F},
+ {0x3D, 0x90}, {0x00, 0x91},
+ {0xCD, 0x92}, {0x0f, 0x93},
+ {0xf7, 0x94}, {0x0f, 0x95},
+ {0x0C, 0x96}, {0x00, 0x97},
+ {0x00, 0x98}, {0x66, 0x99},
+ {0x05, 0x9A}, {0x00, 0x9B},
+ {0x04, 0x9C}, {0x00, 0x9D},
+ {0x08, 0x9E}, {0x00, 0x9F},
+ {0x2D, 0xC0}, {0x2D, 0xC1},
+ {0x3A, 0xC2}, {0x05, 0xC3},
+ {0x04, 0xC4}, {0x3F, 0xC5},
+ {0x00, 0xC6}, {0x00, 0xC7},
+ {0x50, 0xC8}, {0x3C, 0xC9},
+ {0x28, 0xCA}, {0xD8, 0xCB},
+ {0x14, 0xCC}, {0xEC, 0xCD},
+ {0x32, 0xCE}, {0xDD, 0xCF},
+ {0x32, 0xD0}, {0xDD, 0xD1},
+ {0x6A, 0xD2}, {0x50, 0xD3},
+ {0x00, 0xD4}, {0x00, 0xD5},
+ {0x00, 0xD6});
+ break;
+ default:
+ break;
+ }
err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id, 0x0d,
0x00, 0x01, 0, 0);
@@ -65,50 +150,50 @@ static int mi0360_get_ctrl(struct sn9c102_device* cam,
struct v4l2_control* ctrl)
{
struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
- u8 data[5+1];
+ u8 data[2];
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x09, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[2];
+ ctrl->value = data[0];
return 0;
case V4L2_CID_GAIN:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x35, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3];
+ ctrl->value = data[1];
return 0;
case V4L2_CID_RED_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2c, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3];
+ ctrl->value = data[1];
return 0;
case V4L2_CID_BLUE_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2d, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3];
+ ctrl->value = data[1];
return 0;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x2e, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3];
+ ctrl->value = data[1];
return 0;
case V4L2_CID_HFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3] & 0x20 ? 1 : 0;
+ ctrl->value = data[1] & 0x20 ? 1 : 0;
return 0;
case V4L2_CID_VFLIP:
- if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20,
- 2+1, data) < 0)
+ if (sn9c102_i2c_try_raw_read(cam, s, s->i2c_slave_id, 0x20, 2,
+ data) < 0)
return -EIO;
- ctrl->value = data[3] & 0x80 ? 1 : 0;
+ ctrl->value = data[1] & 0x80 ? 1 : 0;
return 0;
default:
return -EINVAL;
@@ -178,8 +263,19 @@ static int mi0360_set_crop(struct sn9c102_device* cam,
{
struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
- u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0,
- v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+ u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0;
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1;
+ break;
+ default:
+ break;
+ }
err += sn9c102_write_reg(cam, h_start, 0x12);
err += sn9c102_write_reg(cam, v_start, 0x13);
@@ -194,24 +290,30 @@ static int mi0360_set_pix_format(struct sn9c102_device* cam,
struct sn9c102_sensor* s = sn9c102_get_sensor(cam);
int err = 0;
- if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) {
- err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
- 0x0a, 0x00, 0x02, 0, 0);
- err += sn9c102_write_reg(cam, 0x20, 0x19);
- } else {
+ if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) {
err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
0x0a, 0x00, 0x05, 0, 0);
err += sn9c102_write_reg(cam, 0x60, 0x19);
+ if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+ sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+ err += sn9c102_write_reg(cam, 0xa6, 0x17);
+ } else {
+ err += sn9c102_i2c_try_raw_write(cam, s, 4, s->i2c_slave_id,
+ 0x0a, 0x00, 0x02, 0, 0);
+ err += sn9c102_write_reg(cam, 0x20, 0x19);
+ if (sn9c102_get_bridge(cam) == BRIDGE_SN9C105 ||
+ sn9c102_get_bridge(cam) == BRIDGE_SN9C120)
+ err += sn9c102_write_reg(cam, 0xa2, 0x17);
}
return err;
}
-static struct sn9c102_sensor mi0360 = {
+static const struct sn9c102_sensor mi0360 = {
.name = "MI-0360",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
- .supported_bridge = BRIDGE_SN9C103,
+ .supported_bridge = BRIDGE_SN9C103 | BRIDGE_SN9C105 | BRIDGE_SN9C120,
.frequency = SN9C102_I2C_100KHZ,
.interface = SN9C102_I2C_2WIRES,
.i2c_slave_id = 0x5d,
@@ -317,19 +419,31 @@ static struct sn9c102_sensor mi0360 = {
int sn9c102_probe_mi0360(struct sn9c102_device* cam)
{
- u8 data[5+1];
- int err;
- err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
- {0x28, 0x17});
- if (err)
- return -EIO;
+ u8 data[2];
+
+ switch (sn9c102_get_bridge(cam)) {
+ case BRIDGE_SN9C103:
+ if (sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
+ return -EIO;
+ break;
+ case BRIDGE_SN9C105:
+ case BRIDGE_SN9C120:
+ if (sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1},
+ {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17}))
+ return -EIO;
+ break;
+ default:
+ break;
+ }
if (sn9c102_i2c_try_raw_read(cam, &mi0360, mi0360.i2c_slave_id, 0x00,
- 2+1, data) < 0)
+ 2, data) < 0)
return -EIO;
- if (data[2] != 0x82 || data[3] != 0x43)
+ if (data[0] != 0x82 || data[1] != 0x43)
return -ENODEV;
sn9c102_attach_sensor(cam, &mi0360);
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c
index 31b6080b061..e6832347894 100644
--- a/drivers/media/video/sn9c102/sn9c102_ov7630.c
+++ b/drivers/media/video/sn9c102/sn9c102_ov7630.c
@@ -29,9 +29,8 @@ static int ov7630_init(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x00, 0x14},
- {0x60, 0x17}, {0x0f, 0x18},
- {0x50, 0x19});
+ err = sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17},
+ {0x0f, 0x18}, {0x50, 0x19});
err += sn9c102_i2c_write(cam, 0x12, 0x8d);
err += sn9c102_i2c_write(cam, 0x12, 0x0d);
@@ -61,7 +60,6 @@ static int ov7630_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x71, 0x00);
err += sn9c102_i2c_write(cam, 0x74, 0x21);
err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
-
break;
case BRIDGE_SN9C103:
err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
@@ -253,7 +251,7 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor ov7630 = {
+static const struct sn9c102_sensor ov7630 = {
.name = "OV7630",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -408,19 +406,16 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x01, 0x01},
- {0x00, 0x01}, {0x28, 0x17});
-
+ err = sn9c102_write_const_regs(cam, {0x01, 0x01}, {0x00, 0x01},
+ {0x28, 0x17});
break;
case BRIDGE_SN9C103: /* do _not_ change anything! */
- err = sn9c102_write_const_regs(cam, {0x09, 0x01},
- {0x42, 0x01}, {0x28, 0x17},
- {0x44, 0x02});
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x42, 0x01},
+ {0x28, 0x17}, {0x44, 0x02});
pid = sn9c102_i2c_try_read(cam, &ov7630, 0x0a);
- if (err || pid < 0) { /* try a different initialization */
- err = sn9c102_write_reg(cam, 0x01, 0x01);
- err += sn9c102_write_reg(cam, 0x00, 0x01);
- }
+ if (err || pid < 0) /* try a different initialization */
+ err += sn9c102_write_const_regs(cam, {0x01, 0x01},
+ {0x00, 0x01});
break;
default:
break;
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7660.c b/drivers/media/video/sn9c102/sn9c102_ov7660.c
index c898e948fe8..4b6474048a7 100644
--- a/drivers/media/video/sn9c102/sn9c102_ov7660.c
+++ b/drivers/media/video/sn9c102/sn9c102_ov7660.c
@@ -104,8 +104,8 @@ static int ov7660_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x12, 0x80);
err += sn9c102_i2c_write(cam, 0x11, 0x09);
err += sn9c102_i2c_write(cam, 0x00, 0x0A);
- err += sn9c102_i2c_write(cam, 0x01, 0x78);
- err += sn9c102_i2c_write(cam, 0x02, 0x90);
+ err += sn9c102_i2c_write(cam, 0x01, 0x80);
+ err += sn9c102_i2c_write(cam, 0x02, 0x80);
err += sn9c102_i2c_write(cam, 0x03, 0x00);
err += sn9c102_i2c_write(cam, 0x04, 0x00);
err += sn9c102_i2c_write(cam, 0x05, 0x08);
@@ -122,7 +122,7 @@ static int ov7660_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x10, 0x20);
err += sn9c102_i2c_write(cam, 0x11, 0x03);
err += sn9c102_i2c_write(cam, 0x12, 0x05);
- err += sn9c102_i2c_write(cam, 0x13, 0xF8);
+ err += sn9c102_i2c_write(cam, 0x13, 0xC7);
err += sn9c102_i2c_write(cam, 0x14, 0x2C);
err += sn9c102_i2c_write(cam, 0x15, 0x00);
err += sn9c102_i2c_write(cam, 0x16, 0x02);
@@ -162,7 +162,7 @@ static int ov7660_init(struct sn9c102_device* cam)
err += sn9c102_i2c_write(cam, 0x38, 0x02);
err += sn9c102_i2c_write(cam, 0x39, 0x43);
err += sn9c102_i2c_write(cam, 0x3A, 0x00);
- err += sn9c102_i2c_write(cam, 0x3B, 0x02);
+ err += sn9c102_i2c_write(cam, 0x3B, 0x0A);
err += sn9c102_i2c_write(cam, 0x3C, 0x6C);
err += sn9c102_i2c_write(cam, 0x3D, 0x99);
err += sn9c102_i2c_write(cam, 0x3E, 0x0E);
@@ -281,25 +281,34 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam,
return -EIO;
break;
case V4L2_CID_DO_WHITE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x02);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x02)) < 0)
+ return -EIO;
ctrl->value = (ctrl->value & 0x04) ? 1 : 0;
break;
case V4L2_CID_RED_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x05);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x05)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
case V4L2_CID_BLUE_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x06);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x06)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
case SN9C102_V4L2_CID_GREEN_BALANCE:
- ctrl->value = sn9c102_pread_reg(cam, 0x07);
+ if ((ctrl->value = sn9c102_read_reg(cam, 0x07)) < 0)
+ return -EIO;
ctrl->value &= 0x7f;
break;
+ case SN9C102_V4L2_CID_BAND_FILTER:
+ if ((ctrl->value = sn9c102_i2c_read(cam, 0x3b)) < 0)
+ return -EIO;
+ ctrl->value &= 0x08;
+ break;
case V4L2_CID_GAIN:
if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0)
return -EIO;
- ctrl->value &= 0x7f;
+ ctrl->value &= 0x1f;
break;
case V4L2_CID_AUTOGAIN:
if ((ctrl->value = sn9c102_i2c_read(cam, 0x13)) < 0)
@@ -335,12 +344,15 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam,
case SN9C102_V4L2_CID_GREEN_BALANCE:
err += sn9c102_write_reg(cam, ctrl->value, 0x07);
break;
+ case SN9C102_V4L2_CID_BAND_FILTER:
+ err += sn9c102_i2c_write(cam, ctrl->value << 3, 0x3b);
+ break;
case V4L2_CID_GAIN:
- err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+ err += sn9c102_i2c_write(cam, 0x00, 0x60 + ctrl->value);
break;
case V4L2_CID_AUTOGAIN:
- err += sn9c102_i2c_write(cam, 0x13, 0xf0 | ctrl->value |
- (ctrl->value << 1));
+ err += sn9c102_i2c_write(cam, 0x13, 0xc0 |
+ (ctrl->value * 0x07));
break;
default:
return -EINVAL;
@@ -386,7 +398,7 @@ static int ov7660_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor ov7660 = {
+static const struct sn9c102_sensor ov7660 = {
.name = "OV7660",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C105 | BRIDGE_SN9C120,
@@ -401,9 +413,9 @@ static struct sn9c102_sensor ov7660 = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "global gain",
.minimum = 0x00,
- .maximum = 0x7f,
+ .maximum = 0x1f,
.step = 0x01,
- .default_value = 0x0a,
+ .default_value = 0x09,
.flags = 0,
},
{
@@ -413,7 +425,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0xff,
.step = 0x01,
- .default_value = 0x50,
+ .default_value = 0x27,
.flags = 0,
},
{
@@ -433,7 +445,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x1f,
+ .default_value = 0x14,
.flags = 0,
},
{
@@ -443,7 +455,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x1e,
+ .default_value = 0x14,
.flags = 0,
},
{
@@ -453,7 +465,7 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x01,
.step = 0x01,
- .default_value = 0x00,
+ .default_value = 0x01,
.flags = 0,
},
{
@@ -463,7 +475,17 @@ static struct sn9c102_sensor ov7660 = {
.minimum = 0x00,
.maximum = 0x7f,
.step = 0x01,
- .default_value = 0x20,
+ .default_value = 0x14,
+ .flags = 0,
+ },
+ {
+ .id = SN9C102_V4L2_CID_BAND_FILTER,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "band filter",
+ .minimum = 0x00,
+ .maximum = 0x01,
+ .step = 0x01,
+ .default_value = 0x00,
.flags = 0,
},
},
@@ -508,6 +530,7 @@ int sn9c102_probe_ov7660(struct sn9c102_device* cam)
return -EIO;
if (pid != 0x76 || ver != 0x60)
return -ENODEV;
+
sn9c102_attach_sensor(cam, &ov7660);
return 0;
diff --git a/drivers/media/video/sn9c102/sn9c102_pas106b.c b/drivers/media/video/sn9c102/sn9c102_pas106b.c
index 67151964801..360f2a848bc 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas106b.c
+++ b/drivers/media/video/sn9c102/sn9c102_pas106b.c
@@ -163,7 +163,7 @@ static int pas106b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor pas106b = {
+static const struct sn9c102_sensor pas106b = {
.name = "PAS106B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
@@ -273,23 +273,21 @@ static struct sn9c102_sensor pas106b = {
int sn9c102_probe_pas106b(struct sn9c102_device* cam)
{
- int r0 = 0, r1 = 0, err;
+ int r0 = 0, r1 = 0;
unsigned int pid = 0;
/*
Minimal initialization to enable the I2C communication
NOTE: do NOT change the values!
*/
- err = sn9c102_write_const_regs(cam,
- {0x01, 0x01}, /* sensor power down */
- {0x00, 0x01}, /* sensor power on */
- {0x28, 0x17});/* sensor clock 24 MHz */
- if (err)
+ if (sn9c102_write_const_regs(cam,
+ {0x01, 0x01}, /* sensor power down */
+ {0x00, 0x01}, /* sensor power on */
+ {0x28, 0x17})) /* sensor clock at 24 MHz */
return -EIO;
r0 = sn9c102_i2c_try_read(cam, &pas106b, 0x00);
r1 = sn9c102_i2c_try_read(cam, &pas106b, 0x01);
-
if (r0 < 0 || r1 < 0)
return -EIO;
diff --git a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
index c1b8d6b63b4..ca4a1506ed3 100644
--- a/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
+++ b/drivers/media/video/sn9c102/sn9c102_pas202bcb.c
@@ -35,29 +35,28 @@ static int pas202bcb_init(struct sn9c102_device* cam)
switch (sn9c102_get_bridge(cam)) {
case BRIDGE_SN9C101:
case BRIDGE_SN9C102:
- err = sn9c102_write_const_regs(cam, {0x00, 0x10},
- {0x00, 0x11}, {0x00, 0x14},
- {0x20, 0x17}, {0x30, 0x19},
- {0x09, 0x18});
+ err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x30, 0x19}, {0x09, 0x18});
break;
case BRIDGE_SN9C103:
- err = sn9c102_write_const_regs(cam, {0x00, 0x02},
- {0x00, 0x03}, {0x1a, 0x04},
- {0x20, 0x05}, {0x20, 0x06},
- {0x20, 0x07}, {0x00, 0x10},
- {0x00, 0x11}, {0x00, 0x14},
- {0x20, 0x17}, {0x30, 0x19},
- {0x09, 0x18}, {0x02, 0x1c},
- {0x03, 0x1d}, {0x0f, 0x1e},
- {0x0c, 0x1f}, {0x00, 0x20},
- {0x10, 0x21}, {0x20, 0x22},
- {0x30, 0x23}, {0x40, 0x24},
- {0x50, 0x25}, {0x60, 0x26},
- {0x70, 0x27}, {0x80, 0x28},
- {0x90, 0x29}, {0xa0, 0x2a},
- {0xb0, 0x2b}, {0xc0, 0x2c},
- {0xd0, 0x2d}, {0xe0, 0x2e},
- {0xf0, 0x2f}, {0xff, 0x30});
+ err = sn9c102_write_const_regs(cam, {0x00, 0x02}, {0x00, 0x03},
+ {0x1a, 0x04}, {0x20, 0x05},
+ {0x20, 0x06}, {0x20, 0x07},
+ {0x00, 0x10}, {0x00, 0x11},
+ {0x00, 0x14}, {0x20, 0x17},
+ {0x30, 0x19}, {0x09, 0x18},
+ {0x02, 0x1c}, {0x03, 0x1d},
+ {0x0f, 0x1e}, {0x0c, 0x1f},
+ {0x00, 0x20}, {0x10, 0x21},
+ {0x20, 0x22}, {0x30, 0x23},
+ {0x40, 0x24}, {0x50, 0x25},
+ {0x60, 0x26}, {0x70, 0x27},
+ {0x80, 0x28}, {0x90, 0x29},
+ {0xa0, 0x2a}, {0xb0, 0x2b},
+ {0xc0, 0x2c}, {0xd0, 0x2d},
+ {0xe0, 0x2e}, {0xf0, 0x2f},
+ {0xff, 0x30});
break;
default:
break;
@@ -197,7 +196,7 @@ static int pas202bcb_set_crop(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor pas202bcb = {
+static const struct sn9c102_sensor pas202bcb = {
.name = "PAS202BCB",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103,
@@ -313,9 +312,8 @@ int sn9c102_probe_pas202bcb(struct sn9c102_device* cam)
{0x28, 0x17});/* clock 24 MHz */
break;
case BRIDGE_SN9C103: /* do _not_ change anything! */
- err = sn9c102_write_const_regs(cam, {0x09, 0x01},
- {0x44, 0x01}, {0x44, 0x02},
- {0x29, 0x17});
+ err = sn9c102_write_const_regs(cam, {0x09, 0x01}, {0x44, 0x01},
+ {0x44, 0x02}, {0x29, 0x17});
break;
default:
break;
diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h
index 1bbf64c897a..2d7d786b843 100644
--- a/drivers/media/video/sn9c102/sn9c102_sensor.h
+++ b/drivers/media/video/sn9c102/sn9c102_sensor.h
@@ -22,7 +22,7 @@
#define _SN9C102_SENSOR_H_
#include <linux/usb.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/device.h>
#include <linux/stddef.h>
#include <linux/errno.h>
@@ -74,7 +74,7 @@ sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id);
/* Attach a probed sensor to the camera. */
extern void
sn9c102_attach_sensor(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor);
+ const struct sn9c102_sensor* sensor);
/*
Read/write routines: they always return -1 on error, 0 or the read value
@@ -85,10 +85,11 @@ sn9c102_attach_sensor(struct sn9c102_device* cam,
*/
/* The "try" I2C I/O versions are used when probing the sensor */
-extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
- u8 address, u8 value);
-extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
- u8 address);
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,
+ const struct sn9c102_sensor*, u8 address,
+ u8 value);
+extern int sn9c102_i2c_try_read(struct sn9c102_device*,
+ const struct sn9c102_sensor*, u8 address);
/*
These must be used if and only if the sensor doesn't implement the standard
@@ -102,29 +103,31 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
byte.
*/
extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 n,
+ const struct sn9c102_sensor* sensor, u8 n,
u8 data0, u8 data1, u8 data2, u8 data3,
u8 data4, u8 data5);
extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam,
- struct sn9c102_sensor* sensor, u8 data0,
- u8 data1, u8 n, u8 buffer[]);
+ const struct sn9c102_sensor* sensor,
+ u8 data0, u8 data1, u8 n, u8 buffer[]);
/* To be used after the sensor struct has been attached to the camera struct */
extern int sn9c102_i2c_write(struct sn9c102_device*, u8 address, u8 value);
extern int sn9c102_i2c_read(struct sn9c102_device*, u8 address);
/* I/O on registers in the bridge. Could be used by the sensor methods too */
+extern int sn9c102_read_reg(struct sn9c102_device*, u16 index);
extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index);
extern int sn9c102_write_reg(struct sn9c102_device*, u8 value, u16 index);
extern int sn9c102_write_regs(struct sn9c102_device*, const u8 valreg[][2],
int count);
/*
- * Write multiple registers with constant values. For example:
- * sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
- */
-#define sn9c102_write_const_regs(device, data...) \
- ({ const static u8 _data[][2] = {data}; \
- sn9c102_write_regs(device, _data, ARRAY_SIZE(_data)); })
+ Write multiple registers with constant values. For example:
+ sn9c102_write_const_regs(cam, {0x00, 0x14}, {0x60, 0x17}, {0x0f, 0x18});
+ Register adresses must be < 256.
+*/
+#define sn9c102_write_const_regs(sn9c102_device, data...) \
+ ({ const static u8 _valreg[][2] = {data}; \
+ sn9c102_write_regs(sn9c102_device, _valreg, ARRAY_SIZE(_valreg)); })
/*****************************************************************************/
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
index 0e7ec8662c7..e7d2de2bace 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
+++ b/drivers/media/video/sn9c102/sn9c102_tas5110c1b.c
@@ -88,7 +88,7 @@ static int tas5110c1b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor tas5110c1b = {
+static const struct sn9c102_sensor tas5110c1b = {
.name = "TAS5110C1B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5110d.c b/drivers/media/video/sn9c102/sn9c102_tas5110d.c
index 83a39e8b5e7..d32fdbccdc5 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5110d.c
+++ b/drivers/media/video/sn9c102/sn9c102_tas5110d.c
@@ -68,7 +68,7 @@ static int tas5110d_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor tas5110d = {
+static const struct sn9c102_sensor tas5110d = {
.name = "TAS5110D",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
diff --git a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
index 50406503fc4..56fb1d575a8 100644
--- a/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
+++ b/drivers/media/video/sn9c102/sn9c102_tas5130d1b.c
@@ -89,7 +89,7 @@ static int tas5130d1b_set_pix_format(struct sn9c102_device* cam,
}
-static struct sn9c102_sensor tas5130d1b = {
+static const struct sn9c102_sensor tas5130d1b = {
.name = "TAS5130D1B",
.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
.supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102,
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig
index a0fd82b924f..e4cb99c1f94 100644
--- a/drivers/media/video/usbvideo/Kconfig
+++ b/drivers/media/video/usbvideo/Kconfig
@@ -3,7 +3,7 @@ config VIDEO_USBVIDEO
config USB_VICAM
tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
- depends on USB && VIDEO_DEV && VIDEO_V4L1 && EXPERIMENTAL
+ depends on VIDEO_V4L1 && EXPERIMENTAL
select VIDEO_USBVIDEO
---help---
Say Y here if you have 3com homeconnect camera (vicam).
@@ -13,7 +13,7 @@ config USB_VICAM
config USB_IBMCAM
tristate "USB IBM (Xirlink) C-it Camera support"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want to connect a IBM "C-It" camera, also known as
@@ -28,7 +28,7 @@ config USB_IBMCAM
config USB_KONICAWC
tristate "USB Konica Webcam support"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want support for webcams based on a Konica
@@ -39,7 +39,7 @@ config USB_KONICAWC
config USB_QUICKCAM_MESSENGER
tristate "USB Logitech Quickcam Messenger"
- depends on USB && VIDEO_DEV && VIDEO_V4L1
+ depends on VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y or M here to enable support for the USB Logitech Quickcam
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig
index c43a5d89909..fc24ef05b3f 100644
--- a/drivers/media/video/usbvision/Kconfig
+++ b/drivers/media/video/usbvision/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
- depends on I2C && VIDEO_V4L2 && USB
+ depends on I2C && VIDEO_V4L2
select VIDEO_TUNER
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
---help---
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index a861e150865..ede8543818b 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -127,7 +127,7 @@ set_v4l_control(struct inode *inode,
/* ----------------------------------------------------------------- */
-static int palette2pixelformat[] = {
+const static unsigned int palette2pixelformat[] = {
[VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
[VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
[VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
@@ -145,7 +145,7 @@ static int palette2pixelformat[] = {
[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
};
-static unsigned int
+static unsigned int __attribute_pure__
palette_to_pixelformat(unsigned int palette)
{
if (palette < ARRAY_SIZE(palette2pixelformat))
@@ -154,8 +154,8 @@ palette_to_pixelformat(unsigned int palette)
return 0;
}
-static unsigned int
-pixelformat_to_palette(int pixelformat)
+static unsigned int __attribute_const__
+pixelformat_to_palette(unsigned int pixelformat)
{
int palette = 0;
switch (pixelformat)
@@ -616,6 +616,8 @@ v4l_compat_translate_ioctl(struct inode *inode,
case VIDIOCSPICT: /* set tone controls & partial capture format */
{
struct video_picture *pict = arg;
+ int mem_err = 0, ovl_err = 0;
+
memset(&fbuf2, 0, sizeof(fbuf2));
set_v4l_control(inode, file,
@@ -628,33 +630,59 @@ v4l_compat_translate_ioctl(struct inode *inode,
V4L2_CID_SATURATION, pict->colour, drv);
set_v4l_control(inode, file,
V4L2_CID_WHITENESS, pict->whiteness, drv);
+ /*
+ * V4L1 uses this ioctl to set both memory capture and overlay
+ * pixel format, while V4L2 has two different ioctls for this.
+ * Some cards may not support one or the other, and may support
+ * different pixel formats for memory vs overlay.
+ */
fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
err = drv(inode, file, VIDIOC_G_FMT, fmt2);
- if (err < 0)
+ /* If VIDIOC_G_FMT failed, then the driver likely doesn't
+ support memory capture. Trying to set the memory capture
+ parameters would be pointless. */
+ if (err < 0) {
dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
- if (fmt2->fmt.pix.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
+ mem_err = -1000; /* didn't even try */
+ } else if (fmt2->fmt.pix.pixelformat !=
+ palette_to_pixelformat(pict->palette)) {
fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
pict->palette);
- err = drv(inode, file, VIDIOC_S_FMT, fmt2);
- if (err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
+ mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
+ if (mem_err < 0)
+ dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
+ mem_err);
}
err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
- if (err < 0)
+ /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
+ support overlay. Trying to set the overlay parameters
+ would be quite pointless. */
+ if (err < 0) {
dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
- if (fbuf2.fmt.pixelformat !=
- palette_to_pixelformat(pict->palette)) {
+ ovl_err = -1000; /* didn't even try */
+ } else if (fbuf2.fmt.pixelformat !=
+ palette_to_pixelformat(pict->palette)) {
fbuf2.fmt.pixelformat = palette_to_pixelformat(
pict->palette);
- err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
- if (err < 0)
- dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err);
- err = 0; /* likely fails for non-root */
+ ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
+ if (ovl_err < 0)
+ dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
+ ovl_err);
}
+ if (ovl_err < 0 && mem_err < 0)
+ /* ioctl failed, couldn't set either parameter */
+ if (mem_err != -1000) {
+ err = mem_err;
+ } else if (ovl_err == -EPERM) {
+ err = 0;
+ } else {
+ err = ovl_err;
+ }
+ else
+ err = 0;
break;
}
case VIDIOCGTUNER: /* get tuner information */
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index 459786ff459..a32dfbe0585 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -702,9 +702,7 @@ videobuf_qbuf(struct videobuf_queue *q,
dprintk(1,"qbuf: memory type is wrong.\n");
goto done;
}
- if (buf->state == STATE_QUEUED ||
- buf->state == STATE_PREPARED ||
- buf->state == STATE_ACTIVE) {
+ if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) {
dprintk(1,"qbuf: buffer is already queued or active.\n");
goto done;
}
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 5263b50463e..b876aca69c7 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -433,13 +433,43 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
int ret = -EINVAL;
if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
- !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
+ !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
v4l_print_ioctl(vfd->name, cmd);
}
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ /***********************************************************
+ Handles calls to the obsoleted V4L1 API
+ Due to the nature of VIDIOCGMBUF, each driver that supports
+ V4L1 should implement its own handler for this ioctl.
+ ***********************************************************/
+
+ /* --- streaming capture ------------------------------------- */
+ if (cmd == VIDIOCGMBUF) {
+ struct video_mbuf *p=arg;
+
+ memset(p,0,sizeof(p));
+
+ if (!vfd->vidiocgmbuf)
+ return ret;
+ ret=vfd->vidiocgmbuf(file, fh, p);
+ if (!ret)
+ dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
+ p->size, p->frames,
+ (unsigned long)p->offsets);
+ return ret;
+ }
+
+ /********************************************************
+ All other V4L1 calls are handled by v4l1_compat module.
+ Those calls will be translated into V4L2 calls, and
+ __video_do_ioctl will be called again, with one or more
+ V4L2 ioctls.
+ ********************************************************/
if (_IOC_TYPE(cmd)=='v')
return v4l_compat_translate_ioctl(inode,file,cmd,arg,
__video_do_ioctl);
+#endif
switch(cmd) {
/* --- capabilities ------------------------------------------ */
@@ -791,24 +821,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
ret=vfd->vidioc_overlay(file, fh, *i);
break;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /* --- streaming capture ------------------------------------- */
- case VIDIOCGMBUF:
- {
- struct video_mbuf *p=arg;
-
- memset(p,0,sizeof(p));
-
- if (!vfd->vidiocgmbuf)
- break;
- ret=vfd->vidiocgmbuf(file, fh, p);
- if (!ret)
- dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
- p->size, p->frames,
- (unsigned long)p->offsets);
- break;
- }
-#endif
case VIDIOC_G_FBUF:
{
struct v4l2_framebuffer *p=arg;
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig
index a859a692018..47cd93f9c7d 100644
--- a/drivers/media/video/zc0301/Kconfig
+++ b/drivers/media/video/zc0301/Kconfig
@@ -1,6 +1,6 @@
config USB_ZC0301
tristate "USB ZC0301[P] Image Processor and Control Chip support"
- depends on USB && VIDEO_V4L1
+ depends on VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on the ZC0301 or
ZC0301P Image Processors and Control Chips.
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index fa489b10c38..fb99cd44550 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1898,8 +1898,12 @@ endmenu
# Gigabit Ethernet
#
-menu "Ethernet (1000 Mbit)"
+menuconfig NETDEV_1000
+ bool "Ethernet (1000 Mbit)"
depends on !UML
+ default y
+
+if NETDEV_1000
config ACENIC
tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
@@ -2299,7 +2303,7 @@ config UGETH_TX_ON_DEMAND
config MV643XX_ETH
tristate "MV-643XX Ethernet support"
- depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32)
+ depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32)
select MII
help
This driver supports the gigabit Ethernet on the Marvell MV643XX
@@ -2326,14 +2330,18 @@ config ATL1
To compile this driver as a module, choose M here. The module
will be called atl1.
-endmenu
+endif # NETDEV_1000
#
# 10 Gigabit Ethernet
#
-menu "Ethernet (10000 Mbit)"
+menuconfig NETDEV_10000
+ bool "Ethernet (10000 Mbit)"
depends on !UML
+ default y
+
+if NETDEV_10000
config CHELSIO_T1
tristate "Chelsio 10Gb Ethernet support"
@@ -2507,7 +2515,7 @@ config MLX4_DEBUG
debug_level module parameter (which can also be set after
the driver is loaded through sysfs).
-endmenu
+endif # NETDEV_10000
source "drivers/net/tokenring/Kconfig"
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index 7c8ccc09b60..829da9a1d11 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -141,6 +141,20 @@ config ACT200L_DONGLE
To activate support for ACTiSYS IR-200L dongle you will have to
start irattach like this: "irattach -d act200l".
+config KINGSUN_DONGLE
+ tristate "KingSun/DonShine DS-620 IrDA-USB dongle"
+ depends on IRDA && USB && EXPERIMENTAL
+ help
+ Say Y or M here if you want to build support for the KingSun/DonShine
+ DS-620 IrDA-USB bridge device driver.
+
+ This USB bridge does not conform to the IrDA-USB device class
+ specification, and therefore needs its own specific driver. This
+ dongle supports SIR speed only (9600 bps).
+
+ To compile it as a module, choose M here: the module will be called
+ kingsun-sir.
+
comment "Old SIR device drivers"
config IRPORT_SIR
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
index 5be09f1b9ee..233a2f92373 100644
--- a/drivers/net/irda/Makefile
+++ b/drivers/net/irda/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o
obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o
obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o
obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o
+obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o
# The SIR helper module
sir-dev-objs := sir_dev.o sir_dongle.o
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
new file mode 100644
index 00000000000..217429122e7
--- /dev/null
+++ b/drivers/net/irda/kingsun-sir.c
@@ -0,0 +1,657 @@
+/*****************************************************************************
+*
+* Filename: kingsun-sir.c
+* Version: 0.1.1
+* Description: Irda KingSun/DonShine USB Dongle
+* Status: Experimental
+* Author: Alex Villac�s Lasso <a_villacis@palosanto.com>
+*
+* Based on stir4200 and mcs7780 drivers, with (strange?) differences
+*
+* 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.
+*
+* 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.
+*
+*****************************************************************************/
+
+/*
+ * This is my current (2007-04-25) understanding of how this dongle is supposed
+ * to work. This is based on reverse-engineering and examination of the packet
+ * data sent and received by the WinXP driver using USBSnoopy. Feel free to
+ * update here as more of this dongle is known:
+ *
+ * General: Unlike the other USB IrDA dongles, this particular dongle exposes,
+ * not two bulk (in and out) endpoints, but two *interrupt* ones. This dongle,
+ * like the bulk based ones (stir4200.c and mcs7780.c), requires polling in
+ * order to receive data.
+ * Transmission: Just like stir4200, this dongle uses a raw stream of data,
+ * which needs to be wrapped and escaped in a similar way as in stir4200.c.
+ * Reception: Poll-based, as in stir4200. Each read returns the contents of a
+ * 8-byte buffer, of which the first byte (LSB) indicates the number of bytes
+ * (1-7) of valid data contained within the remaining 7 bytes. For example, if
+ * the buffer had the following contents:
+ * 06 ff ff ff c0 01 04 aa
+ * This means that (06) there are 6 bytes of valid data. The byte 0xaa at the
+ * end is garbage (left over from a previous reception) and is discarded.
+ * If a read returns an "impossible" value as the length of valid data (such as
+ * 0x36) in the first byte, then the buffer is uninitialized (as is the case of
+ * first plug-in) and its contents should be discarded. There is currently no
+ * evidence that the top 5 bits of the 1st byte of the buffer can have values
+ * other than 0 once reception begins.
+ * Once valid bytes are collected, the assembled stream is a sequence of
+ * wrapped IrDA frames that is unwrapped and unescaped as in stir4200.c.
+ * BIG FAT WARNING: the dongle does *not* reset the RX buffer in any way after
+ * a successful read from the host, which means that in absence of further
+ * reception, repeated reads from the dongle will return the exact same
+ * contents repeatedly. Attempts to be smart and cache a previous read seem
+ * to result in corrupted packets, so this driver depends on the unwrap logic
+ * to sort out any repeated reads.
+ * Speed change: no commands observed so far to change speed, assumed fixed
+ * 9600bps (SIR).
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/usb.h>
+#include <linux/device.h>
+#include <linux/crc32.h>
+
+#include <asm/unaligned.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/crc.h>
+
+/*
+ * According to lsusb, 0x07c0 is assigned to
+ * "Code Mercenaries Hard- und Software GmbH"
+ */
+#define KING_VENDOR_ID 0x07c0
+#define KING_PRODUCT_ID 0x4200
+
+/* These are the currently known USB ids */
+static struct usb_device_id dongles[] = {
+ /* KingSun Co,Ltd IrDA/USB Bridge */
+ { USB_DEVICE(KING_VENDOR_ID, KING_PRODUCT_ID) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(usb, dongles);
+
+#define KINGSUN_MTT 0x07
+
+#define KINGSUN_FIFO_SIZE 4096
+#define KINGSUN_EP_IN 0
+#define KINGSUN_EP_OUT 1
+
+struct kingsun_cb {
+ struct usb_device *usbdev; /* init: probe_irda */
+ struct net_device *netdev; /* network layer */
+ struct irlap_cb *irlap; /* The link layer we are binded to */
+ struct net_device_stats stats; /* network statistics */
+ struct qos_info qos;
+
+ __u8 *in_buf; /* receive buffer */
+ __u8 *out_buf; /* transmit buffer */
+ __u8 max_rx; /* max. atomic read from dongle
+ (usually 8), also size of in_buf */
+ __u8 max_tx; /* max. atomic write to dongle
+ (usually 8) */
+
+ iobuff_t rx_buff; /* receive unwrap state machine */
+ struct timeval rx_time;
+ spinlock_t lock;
+ int receiving;
+
+ __u8 ep_in;
+ __u8 ep_out;
+
+ struct urb *tx_urb;
+ struct urb *rx_urb;
+};
+
+/* Callback transmission routine */
+static void kingsun_send_irq(struct urb *urb)
+{
+ struct kingsun_cb *kingsun = urb->context;
+ struct net_device *netdev = kingsun->netdev;
+
+ /* in process of stopping, just drop data */
+ if (!netif_running(kingsun->netdev)) {
+ err("kingsun_send_irq: Network not running!");
+ return;
+ }
+
+ /* unlink, shutdown, unplug, other nasties */
+ if (urb->status != 0) {
+ err("kingsun_send_irq: urb asynchronously failed - %d",
+ urb->status);
+ }
+ netif_wake_queue(netdev);
+}
+
+/*
+ * Called from net/core when new frame is available.
+ */
+static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct kingsun_cb *kingsun;
+ int wraplen;
+ int ret = 0;
+
+ if (skb == NULL || netdev == NULL)
+ return -EINVAL;
+
+ netif_stop_queue(netdev);
+
+ /* the IRDA wrapping routines don't deal with non linear skb */
+ SKB_LINEAR_ASSERT(skb);
+
+ kingsun = netdev_priv(netdev);
+
+ spin_lock(&kingsun->lock);
+
+ /* Append data to the end of whatever data remains to be transmitted */
+ wraplen = async_wrap_skb(skb,
+ kingsun->out_buf,
+ KINGSUN_FIFO_SIZE);
+
+ /* Calculate how much data can be transmitted in this urb */
+ usb_fill_int_urb(kingsun->tx_urb, kingsun->usbdev,
+ usb_sndintpipe(kingsun->usbdev, kingsun->ep_out),
+ kingsun->out_buf, wraplen, kingsun_send_irq,
+ kingsun, 1);
+
+ if ((ret = usb_submit_urb(kingsun->tx_urb, GFP_ATOMIC))) {
+ err("kingsun_hard_xmit: failed tx_urb submit: %d", ret);
+ switch (ret) {
+ case -ENODEV:
+ case -EPIPE:
+ break;
+ default:
+ kingsun->stats.tx_errors++;
+ netif_start_queue(netdev);
+ }
+ } else {
+ kingsun->stats.tx_packets++;
+ kingsun->stats.tx_bytes += skb->len;
+ }
+
+ dev_kfree_skb(skb);
+ spin_unlock(&kingsun->lock);
+
+ return ret;
+}
+
+/* Receive callback function */
+static void kingsun_rcv_irq(struct urb *urb)
+{
+ struct kingsun_cb *kingsun = urb->context;
+ int ret;
+
+ /* in process of stopping, just drop data */
+ if (!netif_running(kingsun->netdev)) {
+ kingsun->receiving = 0;
+ return;
+ }
+
+ /* unlink, shutdown, unplug, other nasties */
+ if (urb->status != 0) {
+ err("kingsun_rcv_irq: urb asynchronously failed - %d",
+ urb->status);
+ kingsun->receiving = 0;
+ return;
+ }
+
+ if (urb->actual_length == kingsun->max_rx) {
+ __u8 *bytes = urb->transfer_buffer;
+ int i;
+
+ /* The very first byte in the buffer indicates the length of
+ valid data in the read. This byte must be in the range
+ 1..kingsun->max_rx -1 . Values outside this range indicate
+ an uninitialized Rx buffer when the dongle has just been
+ plugged in. */
+ if (bytes[0] >= 1 && bytes[0] < kingsun->max_rx) {
+ for (i = 1; i <= bytes[0]; i++) {
+ async_unwrap_char(kingsun->netdev,
+ &kingsun->stats,
+ &kingsun->rx_buff, bytes[i]);
+ }
+ kingsun->netdev->last_rx = jiffies;
+ do_gettimeofday(&kingsun->rx_time);
+ kingsun->receiving =
+ (kingsun->rx_buff.state != OUTSIDE_FRAME)
+ ? 1 : 0;
+ }
+ } else if (urb->actual_length > 0) {
+ err("%s(): Unexpected response length, expected %d got %d",
+ __FUNCTION__, kingsun->max_rx, urb->actual_length);
+ }
+ /* This urb has already been filled in kingsun_net_open */
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+/*
+ * Function kingsun_net_open (dev)
+ *
+ * Network device is taken up. Usually this is done by "ifconfig irda0 up"
+ */
+static int kingsun_net_open(struct net_device *netdev)
+{
+ struct kingsun_cb *kingsun = netdev_priv(netdev);
+ int err = -ENOMEM;
+ char hwname[16];
+
+ /* At this point, urbs are NULL, and skb is NULL (see kingsun_probe) */
+ kingsun->receiving = 0;
+
+ /* Initialize for SIR to copy data directly into skb. */
+ kingsun->rx_buff.in_frame = FALSE;
+ kingsun->rx_buff.state = OUTSIDE_FRAME;
+ kingsun->rx_buff.truesize = IRDA_SKB_MAX_MTU;
+ kingsun->rx_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
+ if (!kingsun->rx_buff.skb)
+ goto free_mem;
+
+ skb_reserve(kingsun->rx_buff.skb, 1);
+ kingsun->rx_buff.head = kingsun->rx_buff.skb->data;
+ do_gettimeofday(&kingsun->rx_time);
+
+ kingsun->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!kingsun->rx_urb)
+ goto free_mem;
+
+ kingsun->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!kingsun->tx_urb)
+ goto free_mem;
+
+ /*
+ * Now that everything should be initialized properly,
+ * Open new IrLAP layer instance to take care of us...
+ */
+ sprintf(hwname, "usb#%d", kingsun->usbdev->devnum);
+ kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname);
+ if (!kingsun->irlap) {
+ err("kingsun-sir: irlap_open failed");
+ goto free_mem;
+ }
+
+ /* Start first reception */
+ usb_fill_int_urb(kingsun->rx_urb, kingsun->usbdev,
+ usb_rcvintpipe(kingsun->usbdev, kingsun->ep_in),
+ kingsun->in_buf, kingsun->max_rx,
+ kingsun_rcv_irq, kingsun, 1);
+ kingsun->rx_urb->status = 0;
+ err = usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
+ if (err) {
+ err("kingsun-sir: first urb-submit failed: %d", err);
+ goto close_irlap;
+ }
+
+ netif_start_queue(netdev);
+
+ /* Situation at this point:
+ - all work buffers allocated
+ - urbs allocated and ready to fill
+ - max rx packet known (in max_rx)
+ - unwrap state machine initialized, in state outside of any frame
+ - receive request in progress
+ - IrLAP layer started, about to hand over packets to send
+ */
+
+ return 0;
+
+ close_irlap:
+ irlap_close(kingsun->irlap);
+ free_mem:
+ if (kingsun->tx_urb) {
+ usb_free_urb(kingsun->tx_urb);
+ kingsun->tx_urb = NULL;
+ }
+ if (kingsun->rx_urb) {
+ usb_free_urb(kingsun->rx_urb);
+ kingsun->rx_urb = NULL;
+ }
+ if (kingsun->rx_buff.skb) {
+ kfree_skb(kingsun->rx_buff.skb);
+ kingsun->rx_buff.skb = NULL;
+ kingsun->rx_buff.head = NULL;
+ }
+ return err;
+}
+
+/*
+ * Function kingsun_net_close (kingsun)
+ *
+ * Network device is taken down. Usually this is done by
+ * "ifconfig irda0 down"
+ */
+static int kingsun_net_close(struct net_device *netdev)
+{
+ struct kingsun_cb *kingsun = netdev_priv(netdev);
+
+ /* Stop transmit processing */
+ netif_stop_queue(netdev);
+
+ /* Mop up receive && transmit urb's */
+ usb_kill_urb(kingsun->tx_urb);
+ usb_kill_urb(kingsun->rx_urb);
+
+ usb_free_urb(kingsun->tx_urb);
+ usb_free_urb(kingsun->rx_urb);
+
+ kingsun->tx_urb = NULL;
+ kingsun->rx_urb = NULL;
+
+ kfree_skb(kingsun->rx_buff.skb);
+ kingsun->rx_buff.skb = NULL;
+ kingsun->rx_buff.head = NULL;
+ kingsun->rx_buff.in_frame = FALSE;
+ kingsun->rx_buff.state = OUTSIDE_FRAME;
+ kingsun->receiving = 0;
+
+ /* Stop and remove instance of IrLAP */
+ if (kingsun->irlap)
+ irlap_close(kingsun->irlap);
+
+ kingsun->irlap = NULL;
+
+ return 0;
+}
+
+/*
+ * IOCTLs : Extra out-of-band network commands...
+ */
+static int kingsun_net_ioctl(struct net_device *netdev, struct ifreq *rq,
+ int cmd)
+{
+ struct if_irda_req *irq = (struct if_irda_req *) rq;
+ struct kingsun_cb *kingsun = netdev_priv(netdev);
+ int ret = 0;
+
+ switch (cmd) {
+ case SIOCSBANDWIDTH: /* Set bandwidth */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ /* Check if the device is still there */
+ if (netif_device_present(kingsun->netdev))
+ /* No observed commands for speed change */
+ ret = -EOPNOTSUPP;
+ break;
+
+ case SIOCSMEDIABUSY: /* Set media busy */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ /* Check if the IrDA stack is still there */
+ if (netif_running(kingsun->netdev))
+ irda_device_set_media_busy(kingsun->netdev, TRUE);
+ break;
+
+ case SIOCGRECEIVING:
+ /* Only approximately true */
+ irq->ifr_receiving = kingsun->receiving;
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ return ret;
+}
+
+/*
+ * Get device stats (for /proc/net/dev and ifconfig)
+ */
+static struct net_device_stats *
+kingsun_net_get_stats(struct net_device *netdev)
+{
+ struct kingsun_cb *kingsun = netdev_priv(netdev);
+ return &kingsun->stats;
+}
+
+/*
+ * This routine is called by the USB subsystem for each new device
+ * in the system. We need to check if the device is ours, and in
+ * this case start handling it.
+ */
+static int kingsun_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct kingsun_cb *kingsun = NULL;
+ struct net_device *net = NULL;
+ int ret = -ENOMEM;
+ int pipe, maxp_in, maxp_out;
+ __u8 ep_in;
+ __u8 ep_out;
+
+ /* Check that there really are two interrupt endpoints.
+ Check based on the one in drivers/usb/input/usbmouse.c
+ */
+ interface = intf->cur_altsetting;
+ if (interface->desc.bNumEndpoints != 2) {
+ err("kingsun-sir: expected 2 endpoints, found %d",
+ interface->desc.bNumEndpoints);
+ return -ENODEV;
+ }
+ endpoint = &interface->endpoint[KINGSUN_EP_IN].desc;
+ if (!usb_endpoint_is_int_in(endpoint)) {
+ err("kingsun-sir: endpoint 0 is not interrupt IN");
+ return -ENODEV;
+ }
+
+ ep_in = endpoint->bEndpointAddress;
+ pipe = usb_rcvintpipe(dev, ep_in);
+ maxp_in = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+ if (maxp_in > 255 || maxp_in <= 1) {
+ err("%s: endpoint 0 has max packet size %d not in range",
+ __FILE__, maxp_in);
+ return -ENODEV;
+ }
+
+ endpoint = &interface->endpoint[KINGSUN_EP_OUT].desc;
+ if (!usb_endpoint_is_int_out(endpoint)) {
+ err("kingsun-sir: endpoint 1 is not interrupt OUT");
+ return -ENODEV;
+ }
+
+ ep_out = endpoint->bEndpointAddress;
+ pipe = usb_sndintpipe(dev, ep_out);
+ maxp_out = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+
+ /* Allocate network device container. */
+ net = alloc_irdadev(sizeof(*kingsun));
+ if(!net)
+ goto err_out1;
+
+ SET_MODULE_OWNER(net);
+ SET_NETDEV_DEV(net, &intf->dev);
+ kingsun = netdev_priv(net);
+ kingsun->irlap = NULL;
+ kingsun->tx_urb = NULL;
+ kingsun->rx_urb = NULL;
+ kingsun->ep_in = ep_in;
+ kingsun->ep_out = ep_out;
+ kingsun->in_buf = NULL;
+ kingsun->out_buf = NULL;
+ kingsun->max_rx = (__u8)maxp_in;
+ kingsun->max_tx = (__u8)maxp_out;
+ kingsun->netdev = net;
+ kingsun->usbdev = dev;
+ kingsun->rx_buff.in_frame = FALSE;
+ kingsun->rx_buff.state = OUTSIDE_FRAME;
+ kingsun->rx_buff.skb = NULL;
+ kingsun->receiving = 0;
+ spin_lock_init(&kingsun->lock);
+
+ /* Allocate input buffer */
+ kingsun->in_buf = (__u8 *)kmalloc(kingsun->max_rx, GFP_KERNEL);
+ if (!kingsun->in_buf)
+ goto free_mem;
+
+ /* Allocate output buffer */
+ kingsun->out_buf = (__u8 *)kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL);
+ if (!kingsun->out_buf)
+ goto free_mem;
+
+ printk(KERN_INFO "KingSun/DonShine IRDA/USB found at address %d, "
+ "Vendor: %x, Product: %x\n",
+ dev->devnum, le16_to_cpu(dev->descriptor.idVendor),
+ le16_to_cpu(dev->descriptor.idProduct));
+
+ /* Initialize QoS for this device */
+ irda_init_max_qos_capabilies(&kingsun->qos);
+
+ /* That's the Rx capability. */
+ kingsun->qos.baud_rate.bits &= IR_9600;
+ kingsun->qos.min_turn_time.bits &= KINGSUN_MTT;
+ irda_qos_bits_to_value(&kingsun->qos);
+
+ /* Override the network functions we need to use */
+ net->hard_start_xmit = kingsun_hard_xmit;
+ net->open = kingsun_net_open;
+ net->stop = kingsun_net_close;
+ net->get_stats = kingsun_net_get_stats;
+ net->do_ioctl = kingsun_net_ioctl;
+
+ ret = register_netdev(net);
+ if (ret != 0)
+ goto free_mem;
+
+ info("IrDA: Registered KingSun/DonShine device %s", net->name);
+
+ usb_set_intfdata(intf, kingsun);
+
+ /* Situation at this point:
+ - all work buffers allocated
+ - urbs not allocated, set to NULL
+ - max rx packet known (in max_rx)
+ - unwrap state machine (partially) initialized, but skb == NULL
+ */
+
+ return 0;
+
+free_mem:
+ if (kingsun->out_buf) kfree(kingsun->out_buf);
+ if (kingsun->in_buf) kfree(kingsun->in_buf);
+ free_netdev(net);
+err_out1:
+ return ret;
+}
+
+/*
+ * The current device is removed, the USB layer tell us to shut it down...
+ */
+static void kingsun_disconnect(struct usb_interface *intf)
+{
+ struct kingsun_cb *kingsun = usb_get_intfdata(intf);
+
+ if (!kingsun)
+ return;
+
+ unregister_netdev(kingsun->netdev);
+
+ /* Mop up receive && transmit urb's */
+ if (kingsun->tx_urb != NULL) {
+ usb_kill_urb(kingsun->tx_urb);
+ usb_free_urb(kingsun->tx_urb);
+ kingsun->tx_urb = NULL;
+ }
+ if (kingsun->rx_urb != NULL) {
+ usb_kill_urb(kingsun->rx_urb);
+ usb_free_urb(kingsun->rx_urb);
+ kingsun->rx_urb = NULL;
+ }
+
+ kfree(kingsun->out_buf);
+ kfree(kingsun->in_buf);
+ free_netdev(kingsun->netdev);
+
+ usb_set_intfdata(intf, NULL);
+}
+
+#ifdef CONFIG_PM
+/* USB suspend, so power off the transmitter/receiver */
+static int kingsun_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct kingsun_cb *kingsun = usb_get_intfdata(intf);
+
+ netif_device_detach(kingsun->netdev);
+ if (kingsun->tx_urb != NULL) usb_kill_urb(kingsun->tx_urb);
+ if (kingsun->rx_urb != NULL) usb_kill_urb(kingsun->rx_urb);
+ return 0;
+}
+
+/* Coming out of suspend, so reset hardware */
+static int kingsun_resume(struct usb_interface *intf)
+{
+ struct kingsun_cb *kingsun = usb_get_intfdata(intf);
+
+ if (kingsun->rx_urb != NULL)
+ usb_submit_urb(kingsun->rx_urb, GFP_KERNEL);
+ netif_device_attach(kingsun->netdev);
+
+ return 0;
+}
+#endif
+
+/*
+ * USB device callbacks
+ */
+static struct usb_driver irda_driver = {
+ .name = "kingsun-sir",
+ .probe = kingsun_probe,
+ .disconnect = kingsun_disconnect,
+ .id_table = dongles,
+#ifdef CONFIG_PM
+ .suspend = kingsun_suspend,
+ .resume = kingsun_resume,
+#endif
+};
+
+/*
+ * Module insertion
+ */
+static int __init kingsun_init(void)
+{
+ return usb_register(&irda_driver);
+}
+module_init(kingsun_init);
+
+/*
+ * Module removal
+ */
+static void __exit kingsun_cleanup(void)
+{
+ /* Deregister the driver and remove all pending instances */
+ usb_deregister(&irda_driver);
+}
+module_exit(kingsun_cleanup);
+
+MODULE_AUTHOR("Alex Villac�s Lasso <a_villacis@palosanto.com>");
+MODULE_DESCRIPTION("IrDA-USB Dongle Driver for KingSun/DonShine");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index acf1c801a1b..af016d0ea1c 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -623,7 +623,7 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev)
priv->eq_table.eq[MLX4_EQ_CATAS].have_irq = 1;
} else {
err = request_irq(dev->pdev->irq, mlx4_interrupt,
- SA_SHIRQ, DRV_NAME, dev);
+ IRQF_SHARED, DRV_NAME, dev);
if (err)
goto err_out_async;
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 4e32bb678ea..2c5c6d20e6e 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -735,7 +735,7 @@ static int netxen_nic_open(struct net_device *netdev)
}
adapter->irq = adapter->ahw.pdev->irq;
err = request_irq(adapter->ahw.pdev->irq, netxen_intr,
- SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
+ IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name,
adapter);
if (err) {
printk(KERN_ERR "request_irq failed with: %d\n", err);
diff --git a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig
index 74f86200124..5d658bc9791 100644
--- a/drivers/net/pcmcia/Kconfig
+++ b/drivers/net/pcmcia/Kconfig
@@ -2,11 +2,9 @@
# PCMCIA Network device configuration
#
-menu "PCMCIA network device support"
- depends on NETDEVICES && PCMCIA!=n
-
-config NET_PCMCIA
+menuconfig NET_PCMCIA
bool "PCMCIA network device support"
+ depends on PCMCIA
---help---
Say Y if you would like to include support for any PCMCIA or CardBus
network adapters, then say Y to the driver for your particular card
@@ -21,9 +19,10 @@ config NET_PCMCIA
If unsure, say N.
+if NET_PCMCIA
+
config PCMCIA_3C589
tristate "3Com 3c589 PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
help
Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA
(PC-card) Ethernet card to your computer.
@@ -33,7 +32,6 @@ config PCMCIA_3C589
config PCMCIA_3C574
tristate "3Com 3c574 PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
help
Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA
(PC-card) Fast Ethernet card to your computer.
@@ -43,7 +41,6 @@ config PCMCIA_3C574
config PCMCIA_FMVJ18X
tristate "Fujitsu FMV-J18x PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
select CRC32
help
Say Y here if you intend to attach a Fujitsu FMV-J18x or compatible
@@ -54,7 +51,6 @@ config PCMCIA_FMVJ18X
config PCMCIA_PCNET
tristate "NE2000 compatible PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
select CRC32
help
Say Y here if you intend to attach an NE2000 compatible PCMCIA
@@ -65,7 +61,6 @@ config PCMCIA_PCNET
config PCMCIA_NMCLAN
tristate "New Media PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
help
Say Y here if you intend to attach a New Media Ethernet or LiveWire
PCMCIA (PC-card) Ethernet card to your computer.
@@ -75,7 +70,6 @@ config PCMCIA_NMCLAN
config PCMCIA_SMC91C92
tristate "SMC 91Cxx PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
select CRC32
select MII
help
@@ -87,7 +81,6 @@ config PCMCIA_SMC91C92
config PCMCIA_XIRC2PS
tristate "Xircom 16-bit PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
help
Say Y here if you intend to attach a Xircom 16-bit PCMCIA (PC-card)
Ethernet or Fast Ethernet card to your computer.
@@ -97,7 +90,6 @@ config PCMCIA_XIRC2PS
config PCMCIA_AXNET
tristate "Asix AX88190 PCMCIA support"
- depends on NET_PCMCIA && PCMCIA
---help---
Say Y here if you intend to attach an Asix AX88190-based PCMCIA
(PC-card) Fast Ethernet card to your computer. These cards are
@@ -109,7 +101,7 @@ config PCMCIA_AXNET
config ARCNET_COM20020_CS
tristate "COM20020 ARCnet PCMCIA support"
- depends on NET_PCMCIA && ARCNET_COM20020 && PCMCIA
+ depends on ARCNET_COM20020
help
Say Y here if you intend to attach this type of ARCnet PCMCIA card
to your computer.
@@ -119,7 +111,7 @@ config ARCNET_COM20020_CS
config PCMCIA_IBMTR
tristate "IBM PCMCIA tokenring adapter support"
- depends on NET_PCMCIA && IBMTR!=y && TR && PCMCIA && !64BIT
+ depends on IBMTR!=y && TR && !64BIT
help
Say Y here if you intend to attach this type of Token Ring PCMCIA
card to your computer. You then also need to say Y to "Token Ring
@@ -128,5 +120,4 @@ config PCMCIA_IBMTR
To compile this driver as a module, choose M here: the module will be
called ibmtr_cs.
-endmenu
-
+endif # NET_PCMCIA
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index c0d3101eb6a..09b6f259eb9 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -2,70 +2,61 @@
# PHY Layer Configuration
#
-menu "PHY device support"
- depends on !S390
-
-config PHYLIB
+menuconfig PHYLIB
tristate "PHY Device support and infrastructure"
+ depends on !S390
depends on NET_ETHERNET && (BROKEN || !S390)
help
Ethernet controllers are usually attached to PHY
devices. This option provides infrastructure for
managing PHY devices.
+if PHYLIB
+
comment "MII PHY device drivers"
- depends on PHYLIB
config MARVELL_PHY
tristate "Drivers for Marvell PHYs"
- depends on PHYLIB
---help---
Currently has a driver for the 88E1011S
config DAVICOM_PHY
tristate "Drivers for Davicom PHYs"
- depends on PHYLIB
---help---
Currently supports dm9161e and dm9131
config QSEMI_PHY
tristate "Drivers for Quality Semiconductor PHYs"
- depends on PHYLIB
---help---
Currently supports the qs6612
config LXT_PHY
tristate "Drivers for the Intel LXT PHYs"
- depends on PHYLIB
---help---
Currently supports the lxt970, lxt971
config CICADA_PHY
tristate "Drivers for the Cicada PHYs"
- depends on PHYLIB
---help---
Currently supports the cis8204
+
config VITESSE_PHY
tristate "Drivers for the Vitesse PHYs"
- depends on PHYLIB
---help---
Currently supports the vsc8244
config SMSC_PHY
tristate "Drivers for SMSC PHYs"
- depends on PHYLIB
---help---
Currently supports the LAN83C185 PHY
config BROADCOM_PHY
tristate "Drivers for Broadcom PHYs"
- depends on PHYLIB
---help---
Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
config FIXED_PHY
tristate "Drivers for PHY emulation on fixed speed/link"
- depends on PHYLIB
---help---
Adds the driver to PHY layer to cover the boards that do not have any PHY bound,
but with the ability to manipulate the speed/link in software. The relevant MII
@@ -80,5 +71,4 @@ config FIXED_MII_100_FDX
bool "Emulation for 100M Fdx fixed PHY behavior"
depends on FIXED_PHY
-endmenu
-
+endif # PHYLIB
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 519baa38be8..7ed632db00d 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -139,7 +139,7 @@ static int dm9161_ack_interrupt(struct phy_device *phydev)
return (err < 0) ? err : 0;
}
-static struct phy_driver dm9161_driver = {
+static struct phy_driver dm9161e_driver = {
.phy_id = 0x0181b880,
.name = "Davicom DM9161E",
.phy_id_mask = 0x0ffffff0,
@@ -147,7 +147,18 @@ static struct phy_driver dm9161_driver = {
.config_init = dm9161_config_init,
.config_aneg = dm9161_config_aneg,
.read_status = genphy_read_status,
- .driver = { .owner = THIS_MODULE,},
+ .driver = { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver dm9161a_driver = {
+ .phy_id = 0x0181b8a0,
+ .name = "Davicom DM9161A",
+ .phy_id_mask = 0x0ffffff0,
+ .features = PHY_BASIC_FEATURES,
+ .config_init = dm9161_config_init,
+ .config_aneg = dm9161_config_aneg,
+ .read_status = genphy_read_status,
+ .driver = { .owner = THIS_MODULE,},
};
static struct phy_driver dm9131_driver = {
@@ -160,31 +171,38 @@ static struct phy_driver dm9131_driver = {
.read_status = genphy_read_status,
.ack_interrupt = dm9161_ack_interrupt,
.config_intr = dm9161_config_intr,
- .driver = { .owner = THIS_MODULE,},
+ .driver = { .owner = THIS_MODULE,},
};
static int __init davicom_init(void)
{
int ret;
- ret = phy_driver_register(&dm9161_driver);
+ ret = phy_driver_register(&dm9161e_driver);
if (ret)
goto err1;
- ret = phy_driver_register(&dm9131_driver);
+ ret = phy_driver_register(&dm9161a_driver);
if (ret)
goto err2;
+
+ ret = phy_driver_register(&dm9131_driver);
+ if (ret)
+ goto err3;
return 0;
- err2:
- phy_driver_unregister(&dm9161_driver);
+ err3:
+ phy_driver_unregister(&dm9161a_driver);
+ err2:
+ phy_driver_unregister(&dm9161e_driver);
err1:
return ret;
}
static void __exit davicom_exit(void)
{
- phy_driver_unregister(&dm9161_driver);
+ phy_driver_unregister(&dm9161e_driver);
+ phy_driver_unregister(&dm9161a_driver);
phy_driver_unregister(&dm9131_driver);
}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 290e1c1f30c..e3e6d410d72 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -84,7 +84,7 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.22.1"
+#define DRV_VERSION "2.0.23.1"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
@@ -281,6 +281,28 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
("lro_out_of_sequence_pkts"),
("lro_flush_due_to_max_pkts"),
("lro_avg_aggr_pkts"),
+ ("mem_alloc_fail_cnt"),
+ ("watchdog_timer_cnt"),
+ ("mem_allocated"),
+ ("mem_freed"),
+ ("link_up_cnt"),
+ ("link_down_cnt"),
+ ("link_up_time"),
+ ("link_down_time"),
+ ("tx_tcode_buf_abort_cnt"),
+ ("tx_tcode_desc_abort_cnt"),
+ ("tx_tcode_parity_err_cnt"),
+ ("tx_tcode_link_loss_cnt"),
+ ("tx_tcode_list_proc_err_cnt"),
+ ("rx_tcode_parity_err_cnt"),
+ ("rx_tcode_abort_cnt"),
+ ("rx_tcode_parity_abort_cnt"),
+ ("rx_tcode_rda_fail_cnt"),
+ ("rx_tcode_unkn_prot_cnt"),
+ ("rx_tcode_fcs_err_cnt"),
+ ("rx_tcode_buf_size_err_cnt"),
+ ("rx_tcode_rxd_corrupt_cnt"),
+ ("rx_tcode_unkn_err_cnt")
};
#define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN
@@ -490,6 +512,7 @@ static int init_shared_mem(struct s2io_nic *nic)
struct mac_info *mac_control;
struct config_param *config;
+ unsigned long long mem_allocated = 0;
mac_control = &nic->mac_control;
config = &nic->config;
@@ -519,6 +542,7 @@ static int init_shared_mem(struct s2io_nic *nic)
"Malloc failed for list_info\n");
return -ENOMEM;
}
+ mem_allocated += list_holder_size;
memset(mac_control->fifos[i].list_info, 0, list_holder_size);
}
for (i = 0; i < config->tx_fifo_num; i++) {
@@ -565,6 +589,7 @@ static int init_shared_mem(struct s2io_nic *nic)
DBG_PRINT(INFO_DBG, "failed for TxDL\n");
return -ENOMEM;
}
+ mem_allocated += PAGE_SIZE;
}
while (k < lst_per_page) {
int l = (j * lst_per_page) + k;
@@ -582,6 +607,7 @@ static int init_shared_mem(struct s2io_nic *nic)
nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL);
if (!nic->ufo_in_band_v)
return -ENOMEM;
+ mem_allocated += (size * sizeof(u64));
/* Allocation and initialization of RXDs in Rings */
size = 0;
@@ -639,6 +665,7 @@ static int init_shared_mem(struct s2io_nic *nic)
rx_blocks->block_virt_addr = tmp_v_addr;
return -ENOMEM;
}
+ mem_allocated += size;
memset(tmp_v_addr, 0, size);
rx_blocks->block_virt_addr = tmp_v_addr;
rx_blocks->block_dma_addr = tmp_p_addr;
@@ -647,6 +674,8 @@ static int init_shared_mem(struct s2io_nic *nic)
GFP_KERNEL);
if (!rx_blocks->rxds)
return -ENOMEM;
+ mem_allocated +=
+ (sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
for (l=0; l<rxd_count[nic->rxd_mode];l++) {
rx_blocks->rxds[l].virt_addr =
rx_blocks->block_virt_addr +
@@ -689,6 +718,7 @@ static int init_shared_mem(struct s2io_nic *nic)
GFP_KERNEL);
if (!mac_control->rings[i].ba)
return -ENOMEM;
+ mem_allocated +=(sizeof(struct buffAdd *) * blk_cnt);
for (j = 0; j < blk_cnt; j++) {
int k = 0;
mac_control->rings[i].ba[j] =
@@ -697,6 +727,8 @@ static int init_shared_mem(struct s2io_nic *nic)
GFP_KERNEL);
if (!mac_control->rings[i].ba[j])
return -ENOMEM;
+ mem_allocated += (sizeof(struct buffAdd) * \
+ (rxd_count[nic->rxd_mode] + 1));
while (k != rxd_count[nic->rxd_mode]) {
ba = &mac_control->rings[i].ba[j][k];
@@ -704,6 +736,8 @@ static int init_shared_mem(struct s2io_nic *nic)
(BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_0_org)
return -ENOMEM;
+ mem_allocated +=
+ (BUF0_LEN + ALIGN_SIZE);
tmp = (unsigned long)ba->ba_0_org;
tmp += ALIGN_SIZE;
tmp &= ~((unsigned long) ALIGN_SIZE);
@@ -713,6 +747,8 @@ static int init_shared_mem(struct s2io_nic *nic)
(BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
if (!ba->ba_1_org)
return -ENOMEM;
+ mem_allocated
+ += (BUF1_LEN + ALIGN_SIZE);
tmp = (unsigned long) ba->ba_1_org;
tmp += ALIGN_SIZE;
tmp &= ~((unsigned long) ALIGN_SIZE);
@@ -736,6 +772,7 @@ static int init_shared_mem(struct s2io_nic *nic)
*/
return -ENOMEM;
}
+ mem_allocated += size;
mac_control->stats_mem_sz = size;
tmp_v_addr = mac_control->stats_mem;
@@ -743,7 +780,7 @@ static int init_shared_mem(struct s2io_nic *nic)
memset(tmp_v_addr, 0, size);
DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name,
(unsigned long long) tmp_p_addr);
-
+ mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
return SUCCESS;
}
@@ -757,12 +794,14 @@ static int init_shared_mem(struct s2io_nic *nic)
static void free_shared_mem(struct s2io_nic *nic)
{
int i, j, blk_cnt, size;
+ u32 ufo_size = 0;
void *tmp_v_addr;
dma_addr_t tmp_p_addr;
struct mac_info *mac_control;
struct config_param *config;
int lst_size, lst_per_page;
struct net_device *dev = nic->dev;
+ int page_num = 0;
if (!nic)
return;
@@ -774,8 +813,9 @@ static void free_shared_mem(struct s2io_nic *nic)
lst_per_page = PAGE_SIZE / lst_size;
for (i = 0; i < config->tx_fifo_num; i++) {
- int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
- lst_per_page);
+ ufo_size += config->tx_cfg[i].fifo_len;
+ page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
+ lst_per_page);
for (j = 0; j < page_num; j++) {
int mem_blks = (j * lst_per_page);
if (!mac_control->fifos[i].list_info)
@@ -790,6 +830,8 @@ static void free_shared_mem(struct s2io_nic *nic)
mac_control->fifos[i].
list_info[mem_blks].
list_phy_addr);
+ nic->mac_control.stats_info->sw_stat.mem_freed
+ += PAGE_SIZE;
}
/* If we got a zero DMA address during allocation,
* free the page now
@@ -803,8 +845,12 @@ static void free_shared_mem(struct s2io_nic *nic)
dev->name);
DBG_PRINT(INIT_DBG, "Virtual address %p\n",
mac_control->zerodma_virt_addr);
+ nic->mac_control.stats_info->sw_stat.mem_freed
+ += PAGE_SIZE;
}
kfree(mac_control->fifos[i].list_info);
+ nic->mac_control.stats_info->sw_stat.mem_freed +=
+ (nic->config.tx_cfg[i].fifo_len *sizeof(struct list_info_hold));
}
size = SIZE_OF_BLOCK;
@@ -819,7 +865,10 @@ static void free_shared_mem(struct s2io_nic *nic)
break;
pci_free_consistent(nic->pdev, size,
tmp_v_addr, tmp_p_addr);
+ nic->mac_control.stats_info->sw_stat.mem_freed += size;
kfree(mac_control->rings[i].rx_blocks[j].rxds);
+ nic->mac_control.stats_info->sw_stat.mem_freed +=
+ ( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
}
}
@@ -836,12 +885,20 @@ static void free_shared_mem(struct s2io_nic *nic)
struct buffAdd *ba =
&mac_control->rings[i].ba[j][k];
kfree(ba->ba_0_org);
+ nic->mac_control.stats_info->sw_stat.\
+ mem_freed += (BUF0_LEN + ALIGN_SIZE);
kfree(ba->ba_1_org);
+ nic->mac_control.stats_info->sw_stat.\
+ mem_freed += (BUF1_LEN + ALIGN_SIZE);
k++;
}
kfree(mac_control->rings[i].ba[j]);
+ nic->mac_control.stats_info->sw_stat.mem_freed += (sizeof(struct buffAdd) *
+ (rxd_count[nic->rxd_mode] + 1));
}
kfree(mac_control->rings[i].ba);
+ nic->mac_control.stats_info->sw_stat.mem_freed +=
+ (sizeof(struct buffAdd *) * blk_cnt);
}
}
@@ -850,9 +907,14 @@ static void free_shared_mem(struct s2io_nic *nic)
mac_control->stats_mem_sz,
mac_control->stats_mem,
mac_control->stats_mem_phy);
+ nic->mac_control.stats_info->sw_stat.mem_freed +=
+ mac_control->stats_mem_sz;
}
- if (nic->ufo_in_band_v)
+ if (nic->ufo_in_band_v) {
kfree(nic->ufo_in_band_v);
+ nic->mac_control.stats_info->sw_stat.mem_freed
+ += (ufo_size * sizeof(u64));
+ }
}
/**
@@ -2122,10 +2184,12 @@ static void free_tx_buffers(struct s2io_nic *nic)
for (i = 0; i < config->tx_fifo_num; i++) {
for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
- txdp = (struct TxD *) mac_control->fifos[i].list_info[j].
- list_virt_addr;
+ txdp = (struct TxD *) \
+ mac_control->fifos[i].list_info[j].list_virt_addr;
skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
if (skb) {
+ nic->mac_control.stats_info->sw_stat.mem_freed
+ += skb->truesize;
dev_kfree_skb(skb);
cnt++;
}
@@ -2186,11 +2250,14 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
/* skb_shinfo(skb)->frag_list will have L4 data payload */
skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
if (skb_shinfo(skb)->frag_list == NULL) {
+ nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
return -ENOMEM ;
}
frag_list = skb_shinfo(skb)->frag_list;
skb->truesize += frag_list->truesize;
+ nic->mac_control.stats_info->sw_stat.mem_allocated
+ += frag_list->truesize;
frag_list->next = NULL;
tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
frag_list->data = tmp;
@@ -2319,8 +2386,12 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
wmb();
first_rxdp->Control_1 |= RXD_OWN_XENA;
}
+ nic->mac_control.stats_info->sw_stat. \
+ mem_alloc_fail_cnt++;
return -ENOMEM ;
}
+ nic->mac_control.stats_info->sw_stat.mem_allocated
+ += skb->truesize;
if (nic->rxd_mode == RXD_MODE_1) {
/* 1 buffer mode - normal operation mode */
memset(rxdp, 0, sizeof(struct RxD1));
@@ -2328,7 +2399,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single
(nic->pdev, skb->data, size - NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
- rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
+ rxdp->Control_2 =
+ SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
} else if (nic->rxd_mode >= RXD_MODE_3A) {
/*
@@ -2342,7 +2414,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
* payload
*/
- /* save the buffer pointers to avoid frequent dma mapping */
+ /* save buffer pointers to avoid frequent dma mapping */
Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
memset(rxdp, 0, sizeof(struct RxD3));
@@ -2364,7 +2436,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
PCI_DMA_FROMDEVICE);
else
pci_dma_sync_single_for_device(nic->pdev,
- (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
+ (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
if (nic->rxd_mode == RXD_MODE_3B) {
@@ -2391,6 +2463,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
} else {
/* 3 buffer mode */
if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
+ nic->mac_control.stats_info->sw_stat.\
+ mem_freed += skb->truesize;
dev_kfree_skb_irq(skb);
if (first_rxdp) {
wmb();
@@ -2491,6 +2565,7 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
PCI_DMA_FROMDEVICE);
memset(rxdp, 0, sizeof(struct RxD3));
}
+ sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
dev_kfree_skb(skb);
atomic_dec(&sp->rx_bufs_left[ring_no]);
}
@@ -2820,13 +2895,35 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
nic->mac_control.stats_info->sw_stat.
parity_err_cnt++;
}
- if ((err >> 48) == 0xA) {
- DBG_PRINT(TX_DBG, "TxD returned due \
- to loss of link\n");
- }
- else {
- DBG_PRINT(ERR_DBG, "***TxD error %llx\n", err);
- }
+
+ /* update t_code statistics */
+ err >>= 48;
+ switch(err) {
+ case 2:
+ nic->mac_control.stats_info->sw_stat.
+ tx_buf_abort_cnt++;
+ break;
+
+ case 3:
+ nic->mac_control.stats_info->sw_stat.
+ tx_desc_abort_cnt++;
+ break;
+
+ case 7:
+ nic->mac_control.stats_info->sw_stat.
+ tx_parity_err_cnt++;
+ break;
+
+ case 10:
+ nic->mac_control.stats_info->sw_stat.
+ tx_link_loss_cnt++;
+ break;
+
+ case 15:
+ nic->mac_control.stats_info->sw_stat.
+ tx_list_proc_err_cnt++;
+ break;
+ }
}
skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
@@ -2839,6 +2936,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
/* Updating the statistics block */
nic->stats.tx_bytes += skb->len;
+ nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
dev_kfree_skb_irq(skb);
get_info.offset++;
@@ -3314,7 +3412,9 @@ static void s2io_reset(struct s2io_nic * sp)
u16 subid, pci_cmd;
int i;
u16 val16;
- unsigned long long reset_cnt = 0;
+ unsigned long long up_cnt, down_cnt, up_time, down_time, reset_cnt;
+ unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
+
DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
__FUNCTION__, sp->dev->name);
@@ -3380,11 +3480,26 @@ new_way:
/* Reset device statistics maintained by OS */
memset(&sp->stats, 0, sizeof (struct net_device_stats));
- /* save reset count */
+
+ up_cnt = sp->mac_control.stats_info->sw_stat.link_up_cnt;
+ down_cnt = sp->mac_control.stats_info->sw_stat.link_down_cnt;
+ up_time = sp->mac_control.stats_info->sw_stat.link_up_time;
+ down_time = sp->mac_control.stats_info->sw_stat.link_down_time;
reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt;
+ mem_alloc_cnt = sp->mac_control.stats_info->sw_stat.mem_allocated;
+ mem_free_cnt = sp->mac_control.stats_info->sw_stat.mem_freed;
+ watchdog_cnt = sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt;
+ /* save link up/down time/cnt, reset/memory/watchdog cnt */
memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
- /* restore reset count */
+ /* restore link up/down time/cnt, reset/memory/watchdog cnt */
+ sp->mac_control.stats_info->sw_stat.link_up_cnt = up_cnt;
+ sp->mac_control.stats_info->sw_stat.link_down_cnt = down_cnt;
+ sp->mac_control.stats_info->sw_stat.link_up_time = up_time;
+ sp->mac_control.stats_info->sw_stat.link_down_time = down_time;
sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt;
+ sp->mac_control.stats_info->sw_stat.mem_allocated = mem_alloc_cnt;
+ sp->mac_control.stats_info->sw_stat.mem_freed = mem_free_cnt;
+ sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt = watchdog_cnt;
/* SXE-002: Configure link and activity LED to turn it off */
subid = sp->pdev->subsystem_device;
@@ -3672,19 +3787,29 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
GFP_KERNEL);
if (nic->entries == NULL) {
- DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
+ __FUNCTION__);
+ nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
return -ENOMEM;
}
- memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+ nic->mac_control.stats_info->sw_stat.mem_allocated
+ += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+ memset(nic->entries, 0,MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
nic->s2io_entries =
kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
GFP_KERNEL);
if (nic->s2io_entries == NULL) {
- DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+ DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
+ __FUNCTION__);
+ nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
kfree(nic->entries);
+ nic->mac_control.stats_info->sw_stat.mem_freed
+ += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
return -ENOMEM;
}
+ nic->mac_control.stats_info->sw_stat.mem_allocated
+ += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
memset(nic->s2io_entries, 0,
MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
@@ -3708,7 +3833,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
rx_mat = readq(&bar0->rx_mat);
for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
rx_mat |= RX_MAT_SET(j, msix_indx);
- nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+ nic->s2io_entries[msix_indx].arg
+ = &nic->mac_control.rings[j];
nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
}
@@ -3717,7 +3843,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
tx_mat = readq(&bar0->tx_mat0_n[7]);
for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
tx_mat |= TX_MAT_SET(i, msix_indx);
- nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+ nic->s2io_entries[msix_indx].arg
+ = &nic->mac_control.rings[j];
nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
}
@@ -3734,7 +3861,11 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
kfree(nic->entries);
+ nic->mac_control.stats_info->sw_stat.mem_freed
+ += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
kfree(nic->s2io_entries);
+ nic->mac_control.stats_info->sw_stat.mem_freed
+ += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
nic->entries = NULL;
nic->s2io_entries = NULL;
nic->avail_msix_vectors = 0;
@@ -3802,10 +3933,16 @@ static int s2io_open(struct net_device *dev)
hw_init_failed:
if (sp->intr_type == MSI_X) {
- if (sp->entries)
+ if (sp->entries) {
kfree(sp->entries);
- if (sp->s2io_entries)
+ sp->mac_control.stats_info->sw_stat.mem_freed
+ += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+ }
+ if (sp->s2io_entries) {
kfree(sp->s2io_entries);
+ sp->mac_control.stats_info->sw_stat.mem_freed
+ += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
+ }
}
return err;
}
@@ -3866,6 +4003,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
config = &sp->config;
DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name);
+
+ if (unlikely(skb->len <= 0)) {
+ DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
+ dev_kfree_skb_any(skb);
+ return 0;
+}
+
spin_lock_irqsave(&sp->tx_lock, flags);
if (atomic_read(&sp->card_state) == CARD_DOWN) {
DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
@@ -3876,7 +4020,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
}
queue = 0;
-
/* Get Fifo number to Transmit based on vlan priority */
if (sp->vlgrp && vlan_tx_tag_present(skb)) {
vlan_tag = vlan_tx_tag_get(skb);
@@ -3900,14 +4043,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
- /* A buffer with no data will be dropped */
- if (!skb->len) {
- DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
- dev_kfree_skb(skb);
- spin_unlock_irqrestore(&sp->tx_lock, flags);
- return 0;
- }
-
offload_type = s2io_offload_type(skb);
if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
txdp->Control_1 |= TXD_TCP_LSO_EN;
@@ -4003,7 +4138,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
put_off, get_off);
netif_stop_queue(dev);
}
-
+ mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
dev->trans_start = jiffies;
spin_unlock_irqrestore(&sp->tx_lock, flags);
@@ -4775,6 +4910,40 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
return 0;
}
+static void s2io_ethtool_gringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct s2io_nic *sp = dev->priv;
+ int i,tx_desc_count=0,rx_desc_count=0;
+
+ if (sp->rxd_mode == RXD_MODE_1)
+ ering->rx_max_pending = MAX_RX_DESC_1;
+ else if (sp->rxd_mode == RXD_MODE_3B)
+ ering->rx_max_pending = MAX_RX_DESC_2;
+ else if (sp->rxd_mode == RXD_MODE_3A)
+ ering->rx_max_pending = MAX_RX_DESC_3;
+
+ ering->tx_max_pending = MAX_TX_DESC;
+ for (i = 0 ; i < sp->config.tx_fifo_num ; i++) {
+ tx_desc_count += sp->config.tx_cfg[i].fifo_len;
+ }
+ DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
+ ering->tx_pending = tx_desc_count;
+ rx_desc_count = 0;
+ for (i = 0 ; i < sp->config.rx_ring_num ; i++) {
+ rx_desc_count += sp->config.rx_cfg[i].num_rxd;
+ }
+ ering->rx_pending = rx_desc_count;
+
+ ering->rx_mini_max_pending = 0;
+ ering->rx_mini_pending = 0;
+ if(sp->rxd_mode == RXD_MODE_1)
+ ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
+ else if (sp->rxd_mode == RXD_MODE_3B)
+ ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
+ ering->rx_jumbo_pending = rx_desc_count;
+}
+
/**
* s2io_ethtool_getpause_data -Pause frame frame generation and reception.
* @sp : private member of the device structure, which is a pointer to the
@@ -4981,8 +5150,11 @@ static void s2io_vpd_read(struct s2io_nic *nic)
strcpy(nic->serial_num, "NOT AVAILABLE");
vpd_data = kmalloc(256, GFP_KERNEL);
- if (!vpd_data)
+ if (!vpd_data) {
+ nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
return;
+ }
+ nic->mac_control.stats_info->sw_stat.mem_allocated += 256;
for (i = 0; i < 256; i +=4 ) {
pci_write_config_byte(nic->pdev, (vpd_addr + 2), i);
@@ -5022,6 +5194,7 @@ static void s2io_vpd_read(struct s2io_nic *nic)
memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
}
kfree(vpd_data);
+ nic->mac_control.stats_info->sw_stat.mem_freed += 256;
}
/**
@@ -5742,6 +5915,30 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
}
else
tmp_stats[i++] = 0;
+ tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.mem_allocated;
+ tmp_stats[i++] = stat_info->sw_stat.mem_freed;
+ tmp_stats[i++] = stat_info->sw_stat.link_up_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.link_down_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.link_up_time;
+ tmp_stats[i++] = stat_info->sw_stat.link_down_time;
+
+ tmp_stats[i++] = stat_info->sw_stat.tx_buf_abort_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.tx_desc_abort_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.tx_parity_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.tx_link_loss_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.tx_list_proc_err_cnt;
+
+ tmp_stats[i++] = stat_info->sw_stat.rx_parity_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_abort_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_parity_abort_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_rda_fail_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_unkn_prot_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_fcs_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt;
}
static int s2io_ethtool_get_regs_len(struct net_device *dev)
@@ -5854,6 +6051,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.get_eeprom_len = s2io_get_eeprom_len,
.get_eeprom = s2io_ethtool_geeprom,
.set_eeprom = s2io_ethtool_seeprom,
+ .get_ringparam = s2io_ethtool_gringparam,
.get_pauseparam = s2io_ethtool_getpause_data,
.set_pauseparam = s2io_ethtool_setpause_data,
.get_rx_csum = s2io_ethtool_get_rx_csum,
@@ -5962,7 +6160,7 @@ static void s2io_tasklet(unsigned long dev_addr)
if (ret == -ENOMEM) {
DBG_PRINT(INFO_DBG, "%s: Out of ",
dev->name);
- DBG_PRINT(ERR_DBG, "memory in tasklet\n");
+ DBG_PRINT(INFO_DBG, "memory in tasklet\n");
break;
} else if (ret == -EFILL) {
DBG_PRINT(INFO_DBG,
@@ -6077,9 +6275,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
*skb = dev_alloc_skb(size);
if (!(*skb)) {
DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
- DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
+ DBG_PRINT(INFO_DBG, "memory to allocate ");
+ DBG_PRINT(INFO_DBG, "1 buf mode SKBs\n");
+ sp->mac_control.stats_info->sw_stat. \
+ mem_alloc_fail_cnt++;
return -ENOMEM ;
}
+ sp->mac_control.stats_info->sw_stat.mem_allocated
+ += (*skb)->truesize;
/* storing the mapped addr in a temp variable
* such it will be used for next rxd whose
* Host Control is NULL
@@ -6099,10 +6302,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
} else {
*skb = dev_alloc_skb(size);
if (!(*skb)) {
- DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
- dev->name);
+ DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+ DBG_PRINT(INFO_DBG, "memory to allocate ");
+ DBG_PRINT(INFO_DBG, "2 buf mode SKBs\n");
+ sp->mac_control.stats_info->sw_stat. \
+ mem_alloc_fail_cnt++;
return -ENOMEM;
}
+ sp->mac_control.stats_info->sw_stat.mem_allocated
+ += (*skb)->truesize;
((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
pci_map_single(sp->pdev, (*skb)->data,
dev->mtu + 4,
@@ -6126,10 +6334,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
} else {
*skb = dev_alloc_skb(size);
if (!(*skb)) {
- DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
- dev->name);
+ DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+ DBG_PRINT(INFO_DBG, "memory to allocate ");
+ DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n");
+ sp->mac_control.stats_info->sw_stat. \
+ mem_alloc_fail_cnt++;
return -ENOMEM;
}
+ sp->mac_control.stats_info->sw_stat.mem_allocated
+ += (*skb)->truesize;
((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
PCI_DMA_FROMDEVICE);
@@ -6147,10 +6360,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
if (skb_shinfo(*skb)->frag_list == NULL) {
DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \
failed\n ", dev->name);
+ sp->mac_control.stats_info->sw_stat. \
+ mem_alloc_fail_cnt++;
return -ENOMEM ;
}
frag_list = skb_shinfo(*skb)->frag_list;
frag_list->next = NULL;
+ sp->mac_control.stats_info->sw_stat.mem_allocated
+ += frag_list->truesize;
/*
* Buffer-2 receives L4 data payload
*/
@@ -6566,6 +6783,7 @@ static void s2io_tx_watchdog(struct net_device *dev)
struct s2io_nic *sp = dev->priv;
if (netif_carrier_ok(dev)) {
+ sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt++;
schedule_work(&sp->rst_timer_task);
sp->mac_control.stats_info->sw_stat.soft_reset_cnt++;
}
@@ -6606,7 +6824,53 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
if (err & 0x1) {
sp->mac_control.stats_info->sw_stat.parity_err_cnt++;
}
+ err >>= 48;
+ switch(err) {
+ case 1:
+ sp->mac_control.stats_info->sw_stat.
+ rx_parity_err_cnt++;
+ break;
+ case 2:
+ sp->mac_control.stats_info->sw_stat.
+ rx_abort_cnt++;
+ break;
+
+ case 3:
+ sp->mac_control.stats_info->sw_stat.
+ rx_parity_abort_cnt++;
+ break;
+
+ case 4:
+ sp->mac_control.stats_info->sw_stat.
+ rx_rda_fail_cnt++;
+ break;
+
+ case 5:
+ sp->mac_control.stats_info->sw_stat.
+ rx_unkn_prot_cnt++;
+ break;
+
+ case 6:
+ sp->mac_control.stats_info->sw_stat.
+ rx_fcs_err_cnt++;
+ break;
+
+ case 7:
+ sp->mac_control.stats_info->sw_stat.
+ rx_buf_size_err_cnt++;
+ break;
+
+ case 8:
+ sp->mac_control.stats_info->sw_stat.
+ rx_rxd_corrupt_cnt++;
+ break;
+
+ case 15:
+ sp->mac_control.stats_info->sw_stat.
+ rx_unkn_err_cnt++;
+ break;
+ }
/*
* Drop the packet if bad transfer code. Exception being
* 0x5, which could be due to unsupported IPv6 extension header.
@@ -6614,10 +6878,12 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
* Note that in this case, since checksum will be incorrect,
* stack will validate the same.
*/
- if (err && ((err >> 48) != 0x5)) {
+ if (err != 0x5) {
DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n",
dev->name, err);
sp->stats.rx_crc_errors++;
+ sp->mac_control.stats_info->sw_stat.mem_freed
+ += skb->truesize;
dev_kfree_skb(skb);
atomic_dec(&sp->rx_bufs_left[ring_no]);
rxdp->Host_Control = 0;
@@ -6627,7 +6893,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
/* Updating statistics */
rxdp->Host_Control = 0;
- sp->stats.rx_packets++;
if (sp->rxd_mode == RXD_MODE_1) {
int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
@@ -6731,7 +6996,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
} else {
skb->ip_summed = CHECKSUM_NONE;
}
-
+ sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
if (!sp->lro) {
skb->protocol = eth_type_trans(skb, dev);
if ((sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2) &&
@@ -6780,12 +7045,21 @@ static void s2io_link(struct s2io_nic * sp, int link)
if (link == LINK_DOWN) {
DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
netif_carrier_off(dev);
+ if(sp->mac_control.stats_info->sw_stat.link_up_cnt)
+ sp->mac_control.stats_info->sw_stat.link_up_time =
+ jiffies - sp->start_time;
+ sp->mac_control.stats_info->sw_stat.link_down_cnt++;
} else {
DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
+ if (sp->mac_control.stats_info->sw_stat.link_down_cnt)
+ sp->mac_control.stats_info->sw_stat.link_down_time =
+ jiffies - sp->start_time;
+ sp->mac_control.stats_info->sw_stat.link_up_cnt++;
netif_carrier_on(dev);
}
}
sp->last_link_state = link;
+ sp->start_time = jiffies;
}
/**
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index a656d18b33d..54baa0b8ec7 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -95,6 +95,32 @@ struct swStat {
unsigned long long flush_max_pkts;
unsigned long long sum_avg_pkts_aggregated;
unsigned long long num_aggregations;
+ /* Other statistics */
+ unsigned long long mem_alloc_fail_cnt;
+ unsigned long long watchdog_timer_cnt;
+ unsigned long long mem_allocated;
+ unsigned long long mem_freed;
+ unsigned long long link_up_cnt;
+ unsigned long long link_down_cnt;
+ unsigned long long link_up_time;
+ unsigned long long link_down_time;
+
+ /* Transfer Code statistics */
+ unsigned long long tx_buf_abort_cnt;
+ unsigned long long tx_desc_abort_cnt;
+ unsigned long long tx_parity_err_cnt;
+ unsigned long long tx_link_loss_cnt;
+ unsigned long long tx_list_proc_err_cnt;
+
+ unsigned long long rx_parity_err_cnt;
+ unsigned long long rx_abort_cnt;
+ unsigned long long rx_parity_abort_cnt;
+ unsigned long long rx_rda_fail_cnt;
+ unsigned long long rx_unkn_prot_cnt;
+ unsigned long long rx_fcs_err_cnt;
+ unsigned long long rx_buf_size_err_cnt;
+ unsigned long long rx_rxd_corrupt_cnt;
+ unsigned long long rx_unkn_err_cnt;
};
/* Xpak releated alarm and warnings */
@@ -308,6 +334,11 @@ struct stat_block {
#define MAX_TX_FIFOS 8
#define MAX_RX_RINGS 8
+#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 )
+#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
+#define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
+#define MAX_TX_DESC (MAX_AVAILABLE_TXDS)
+
/* FIFO mappings for all possible number of fifos configured */
static int fifo_map[][MAX_TX_FIFOS] = {
{0, 0, 0, 0, 0, 0, 0, 0},
@@ -819,6 +850,7 @@ struct s2io_nic {
#define LINK_UP 2
int task_flag;
+ unsigned long long start_time;
#define CARD_DOWN 1
#define CARD_UP 2
atomic_t card_state;
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 1fc77300b05..2106becf699 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -16,11 +16,13 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/platform_device.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
+#include <asm/sgi/seeq.h>
#include "sgiseeq.h"
@@ -92,13 +94,9 @@ struct sgiseeq_private {
struct net_device_stats stats;
- struct net_device *next_module;
spinlock_t tx_lock;
};
-/* A list of all installed seeq devices, for removing the driver module. */
-static struct net_device *root_sgiseeq_dev;
-
static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
{
hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
@@ -624,9 +622,12 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
-static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
+static int __init sgiseeq_probe(struct platform_device *pdev)
{
+ struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
+ struct hpc3_regs *hpcregs = pd->hpc;
struct sgiseeq_init_block *sr;
+ unsigned int irq = pd->irq;
struct sgiseeq_private *sp;
struct net_device *dev;
int err, i;
@@ -637,6 +638,8 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
err = -ENOMEM;
goto err_out;
}
+
+ platform_set_drvdata(pdev, dev);
sp = netdev_priv(dev);
/* Make private data page aligned */
@@ -648,15 +651,7 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
}
sp->srings = sr;
-#define EADDR_NVOFS 250
- for (i = 0; i < 3; i++) {
- unsigned short tmp = has_eeprom ?
- ip22_eeprom_read(&hpcregs->eeprom, EADDR_NVOFS / 2+i) :
- ip22_nvram_read(EADDR_NVOFS / 2+i);
-
- dev->dev_addr[2 * i] = tmp >> 8;
- dev->dev_addr[2 * i + 1] = tmp & 0xff;
- }
+ memcpy(dev->dev_addr, pd->mac, ETH_ALEN);
#ifdef DEBUG
gpriv = sp;
@@ -720,9 +715,6 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
- sp->next_module = root_sgiseeq_dev;
- root_sgiseeq_dev = dev;
-
return 0;
err_out_free_page:
@@ -734,43 +726,42 @@ err_out:
return err;
}
-static int __init sgiseeq_probe(void)
+static void __exit sgiseeq_remove(struct platform_device *pdev)
{
- unsigned int tmp, ret1, ret2 = 0;
-
- /* On board adapter on 1st HPC is always present */
- ret1 = sgiseeq_init(hpc3c0, SGI_ENET_IRQ, 0);
- /* Let's see if second HPC is there */
- if (!(ip22_is_fullhouse()) &&
- get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]) == 0) {
- sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 |
- SGIMC_GIOPAR_EXP164 |
- SGIMC_GIOPAR_HPC264;
- hpc3c1->pbus_piocfg[0][0] = 0x3ffff;
- /* interrupt/config register on Challenge S Mezz board */
- hpc3c1->pbus_extregs[0][0] = 0x30;
- ret2 = sgiseeq_init(hpc3c1, SGI_GIO_0_IRQ, 1);
- }
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct sgiseeq_private *sp = netdev_priv(dev);
- return (ret1 & ret2) ? ret1 : 0;
+ unregister_netdev(dev);
+ free_page((unsigned long) sp->srings);
+ free_netdev(dev);
+ platform_set_drvdata(pdev, NULL);
}
-static void __exit sgiseeq_exit(void)
-{
- struct net_device *next, *dev;
- struct sgiseeq_private *sp;
+static struct platform_driver sgiseeq_driver = {
+ .probe = sgiseeq_probe,
+ .remove = __devexit_p(sgiseeq_remove),
+ .driver = {
+ .name = "sgiseeq"
+ }
+};
- for (dev = root_sgiseeq_dev; dev; dev = next) {
- sp = (struct sgiseeq_private *) netdev_priv(dev);
- next = sp->next_module;
- unregister_netdev(dev);
- free_page((unsigned long) sp->srings);
- free_netdev(dev);
+static int __init sgiseeq_module_init(void)
+{
+ if (platform_driver_register(&sgiseeq_driver)) {
+ printk(KERN_ERR "Driver registration failed\n");
+ return -ENODEV;
}
+
+ return 0;
+}
+
+static void __exit sgiseeq_module_exit(void)
+{
+ platform_driver_unregister(&sgiseeq_driver);
}
-module_init(sgiseeq_probe);
-module_exit(sgiseeq_exit);
+module_init(sgiseeq_module_init);
+module_exit(sgiseeq_module_exit);
MODULE_DESCRIPTION("SGI Seeq 8003 driver");
MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e0489578945..77669294656 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3802,6 +3802,9 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, err, wol = 0;
+ if (!hw)
+ return 0;
+
err = pci_save_state(pdev);
if (err)
return err;
@@ -3830,6 +3833,9 @@ static int skge_resume(struct pci_dev *pdev)
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, err;
+ if (!hw)
+ return 0;
+
err = pci_set_power_state(pdev, PCI_D0);
if (err)
goto out;
@@ -3868,6 +3874,9 @@ static void skge_shutdown(struct pci_dev *pdev)
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, wol = 0;
+ if (!hw)
+ return;
+
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
struct skge_port *skge = netdev_priv(dev);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index a307310f13f..104e20456e6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -40,6 +40,7 @@
#include <linux/if_vlan.h>
#include <linux/prefetch.h>
#include <linux/mii.h>
+#include <linux/dmi.h>
#include <asm/irq.h>
@@ -130,7 +131,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
- { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
{ 0 }
};
@@ -150,6 +151,8 @@ static const char *yukon2_name[] = {
"FE", /* 0xb7 */
};
+static int dmi_blacklisted;
+
/* Access to external PHY */
static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
{
@@ -2531,6 +2534,17 @@ static int __devinit sky2_init(struct sky2_hw *hw)
return -EOPNOTSUPP;
}
+
+ /* Some Gigabyte motherboards have 88e8056 but cause problems
+ * There is some unresolved hardware related problem that causes
+ * descriptor errors and receive data corruption.
+ */
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U && dmi_blacklisted) {
+ dev_err(&hw->pdev->dev,
+ "88E8056 on this motherboard not supported\n");
+ return -EOPNOTSUPP;
+ }
+
hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
hw->ports = 1;
t8 = sky2_read8(hw, B2_Y2_HW_RES);
@@ -3578,17 +3592,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out;
}
- /* Some Gigabyte motherboards have 88e8056 but cause problems
- * There is some unresolved hardware related problem that causes
- * descriptor errors and receive data corruption.
- */
- if (pdev->vendor == PCI_VENDOR_ID_MARVELL &&
- pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) {
- dev_err(&pdev->dev,
- "88E8056 on Gigabyte motherboards not supported\n");
- goto err_out_disable;
- }
-
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
dev_err(&pdev->dev, "cannot obtain PCI resources\n");
@@ -3732,6 +3735,7 @@ err_out_free_regions:
err_out_disable:
pci_disable_device(pdev);
err_out:
+ pci_set_drvdata(pdev, NULL);
return err;
}
@@ -3784,6 +3788,9 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
struct sky2_hw *hw = pci_get_drvdata(pdev);
int i, wol = 0;
+ if (!hw)
+ return 0;
+
del_timer_sync(&hw->idle_timer);
netif_poll_disable(hw->dev[0]);
@@ -3815,6 +3822,9 @@ static int sky2_resume(struct pci_dev *pdev)
struct sky2_hw *hw = pci_get_drvdata(pdev);
int i, err;
+ if (!hw)
+ return 0;
+
err = pci_set_power_state(pdev, PCI_D0);
if (err)
goto out;
@@ -3861,6 +3871,9 @@ static void sky2_shutdown(struct pci_dev *pdev)
struct sky2_hw *hw = pci_get_drvdata(pdev);
int i, wol = 0;
+ if (!hw)
+ return;
+
del_timer_sync(&hw->idle_timer);
netif_poll_disable(hw->dev[0]);
@@ -3897,8 +3910,24 @@ static struct pci_driver sky2_driver = {
.shutdown = sky2_shutdown,
};
+static struct dmi_system_id __initdata broken_dmi_table[] = {
+ {
+ .ident = "Gigabyte 965P-S3",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),
+
+ },
+ },
+ { }
+};
+
static int __init sky2_init_module(void)
{
+ /* Look for sick motherboards */
+ if (dmi_check_system(broken_dmi_table))
+ dmi_blacklisted = 1;
+
return pci_register_driver(&sky2_driver);
}
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c15e97253ed..108adbf5b5e 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -175,12 +175,10 @@ spider_net_setup_aneg(struct spider_net_card *card)
{
struct mii_phy *phy = &card->phy;
u32 advertise = 0;
- u16 bmcr, bmsr, stat1000, estat;
+ u16 bmsr, estat;
- bmcr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMCR);
- bmsr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
- stat1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_STAT1000);
- estat = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
+ bmsr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
+ estat = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
if (bmsr & BMSR_10HALF)
advertise |= ADVERTISED_10baseT_Half;
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 8897f538a7c..4fc8681bc11 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -2,10 +2,7 @@
# wan devices configuration
#
-menu "Wan interfaces"
- depends on NETDEVICES
-
-config WAN
+menuconfig WAN
bool "Wan interfaces support"
---help---
Wide Area Networks (WANs), such as X.25, Frame Relay and leased
@@ -23,10 +20,12 @@ config WAN
If unsure, say N.
+if WAN
+
# There is no way to detect a comtrol sv11 - force it modular for now.
config HOSTESS_SV11
tristate "Comtrol Hostess SV-11 support"
- depends on WAN && ISA && m && ISA_DMA_API && INET
+ depends on ISA && m && ISA_DMA_API && INET
help
Driver for Comtrol Hostess SV-11 network card which
operates on low speed synchronous serial links at up to
@@ -38,7 +37,7 @@ config HOSTESS_SV11
# The COSA/SRP driver has not been tested as non-modular yet.
config COSA
tristate "COSA/SRP sync serial boards support"
- depends on WAN && ISA && m && ISA_DMA_API
+ depends on ISA && m && ISA_DMA_API
---help---
Driver for COSA and SRP synchronous serial boards.
@@ -62,7 +61,7 @@ config COSA
#
config LANMEDIA
tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
- depends on WAN && PCI
+ depends on PCI
---help---
Driver for the following Lan Media family of serial boards:
@@ -89,7 +88,7 @@ config LANMEDIA
# There is no way to detect a Sealevel board. Force it modular
config SEALEVEL_4021
tristate "Sealevel Systems 4021 support"
- depends on WAN && ISA && m && ISA_DMA_API && INET
+ depends on ISA && m && ISA_DMA_API && INET
help
This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
@@ -99,7 +98,6 @@ config SEALEVEL_4021
# Generic HDLC
config HDLC
tristate "Generic HDLC layer"
- depends on WAN
help
Say Y to this option if your Linux box contains a WAN (Wide Area
Network) card supported by this driver and you are planning to
@@ -167,7 +165,7 @@ config HDLC_X25
If unsure, say N.
comment "X.25/LAPB support is disabled"
- depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
+ depends on HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
config PCI200SYN
tristate "Goramo PCI200SYN support"
@@ -230,10 +228,10 @@ config PC300_MLPPP
Multilink PPP over the PC300 synchronous communication boards.
comment "Cyclades-PC300 MLPPP support is disabled."
- depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
+ depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
comment "Refer to the file README.mlppp, provided by PC300 package."
- depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
+ depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
config PC300TOO
tristate "Cyclades PC300 RSV/X21 alternative support"
@@ -338,7 +336,6 @@ config DSCC4_PCI_RST
config DLCI
tristate "Frame Relay DLCI support"
- depends on WAN
---help---
Support for the Frame Relay protocol.
@@ -385,7 +382,7 @@ config SDLA
# Wan router core.
config WAN_ROUTER_DRIVERS
tristate "WAN router drivers"
- depends on WAN && WAN_ROUTER
+ depends on WAN_ROUTER
---help---
Connect LAN to WAN via Linux box.
@@ -440,7 +437,7 @@ config CYCLOMX_X25
# X.25 network drivers
config LAPBETHER
tristate "LAPB over Ethernet driver (EXPERIMENTAL)"
- depends on WAN && LAPB && X25
+ depends on LAPB && X25
---help---
Driver for a pseudo device (typically called /dev/lapb0) which allows
you to open an LAPB point-to-point connection to some other computer
@@ -456,7 +453,7 @@ config LAPBETHER
config X25_ASY
tristate "X.25 async driver (EXPERIMENTAL)"
- depends on WAN && LAPB && X25
+ depends on LAPB && X25
---help---
Send and receive X.25 frames over regular asynchronous serial
lines such as telephone lines equipped with ordinary modems.
@@ -471,7 +468,7 @@ config X25_ASY
config SBNI
tristate "Granch SBNI12 Leased Line adapter support"
- depends on WAN && X86
+ depends on X86
---help---
Driver for ISA SBNI12-xx cards which are low cost alternatives to
leased line modems.
@@ -497,5 +494,4 @@ config SBNI_MULTILINE
If unsure, say N.
-endmenu
-
+endif # WAN
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index 19c935071d8..56a8ea1fbf0 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -1,5 +1,3 @@
-# EXTRA_CFLAGS += -Wpacked
-
usb8xxx-objs := main.o fw.o wext.o \
rx.o tx.o cmd.o \
cmdresp.o scan.o \
@@ -7,13 +5,6 @@ usb8xxx-objs := main.o fw.o wext.o \
ioctl.o debugfs.o \
ethtool.o assoc.o
-ifeq ($(CONFIG_LIBERTAS_USB_DEBUG), y)
-EXTRA_CFLAGS += -DDEBUG -DPROC_DEBUG
-endif
-
-
-# This is needed to support the newer boot2 bootloader (v >= 3104)
-EXTRA_CFLAGS += -DSUPPORT_BOOT_COMMAND
usb8xxx-objs += if_bootcmd.o
usb8xxx-objs += if_usb.o
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index 688da4c784b..378577200b5 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -40,64 +40,11 @@ NAME
SYNOPSIS
iwpriv <ethX> <command> [sub-command] ...
- iwpriv ethX version
- iwpriv ethX scantype [sub-command]
- iwpriv ethX getSNR <n>
- iwpriv ethX getNF <n>
- iwpriv ethX getRSSI <n>
- iwpriv ethX setrxant <n>
- iwpriv ethX getrxant
- iwpriv ethX settxant <n>
- iwpriv ethX gettxant
- iwpriv ethX authalgs <n>
- iwpriv ethX pre-TBTT <n>
- iwpriv ethX 8021xauthalgs <n>
- iwpriv ethX encryptionmode <n>
iwpriv ethX setregioncode <n>
iwpriv ethX getregioncode
- iwpriv ethX setbcnavg <n>
- iwpriv ethX getbcnavg
- iwpriv ethX setdataavg <n>
- iwpriv ethX setlisteninter <n>
- iwpriv ethX getlisteninter
- iwpriv ethX setmultipledtim <n>
- iwpriv ethX getmultipledtim
- iwpriv ethX atimwindow <n>
- iwpriv ethX deauth
- iwpriv ethX adhocstop
- iwpriv ethX radioon
- iwpriv ethX radiooff
- iwpriv ethX reasso-on
- iwpriv ethX reasso-off
- iwpriv ethX scanmode [sub-command]
- iwpriv ethX setwpaie <n>
- iwpriv ethX wlanidle-off
- iwpriv ethX wlanidle-on
- iwpriv ethX getcis
- iwpriv ethX getlog
- iwpriv ethX getadhocstatus
- iwpriv ethX adhocgrate <n>
-
-Version 4 Command:
- iwpriv ethX inactvityto <n>
- iwpriv ethX sleeppd <n>
- iwpriv ethX enable11d <n>
- iwpriv ethX tpccfg <n>
- iwpriv ethX powercfg <n>
- iwpriv ethX setafc <n>
- iwpriv ethX getafc
Version 5 Command:
iwpriv ethX ledgpio <n>
- iwpriv ethX scanprobes <n>
- iwpriv ethX lolisteninter <n>
- iwpriv ethX rateadapt <n> <m>
- iwpriv ethX txcontrol <n>
- iwpriv ethX psnullinterval <n>
- iwpriv ethX prescan <n>
- iwpriv ethX getrxinfo
- iwpriv ethX gettxrate
- iwpriv ethX beaconinterval
BT Commands:
The blinding table (BT) contains a list of mac addresses that should be
@@ -150,114 +97,6 @@ DESCRIPTION
The ethX parameter specifies the network device that is to be used to
perform this command on. it could be eth0, eth1 etc.
-version
- This is used to get the current version of the driver and the firmware.
-
-scantype
- This command is used to set the scan type to be used by the driver in
- the scan command. This setting will not be used while performing a scan
- for a specific SSID, as it is always done with scan type being active.
-
- where the sub-commands are: -
- active -- to set the scan type to active
- passive -- to set the scan type to passive
- get -- to get the scan type set in the driver
-
-getSNR
- This command gets the average and non average value of Signal to Noise
- Ratio of Beacon and Data.
-
- where value is:-
- 0 -- Beacon non-average.
- 1 -- Beacon average.
- 2 -- Data non-average.
- 3 -- Data average.
-
- If no value is given, all four values are returned in the order mentioned
- above.
-
- Note: This command is available only when STA is connected.
-
-getRSSI
- This command gets the average and non average value os Receive Signal
- Strength of Beacon and Data.
-
- where value is:-
- 0 -- Beacon non-average.
- 1 -- Beacon average.
- 2 -- Data non-average.
- 3 -- Data average.
-
- Note: This command is available only when STA is connected.
-
-getNF
- This command gets the average and non average value of Noise Floor of
- Beacon and Data.
-
- where value is:-
- 0 -- Beacon non-average.
- 1 -- Beacon average.
- 2 -- Data non-average.
- 3 -- Data average.
-
- Note: This command is available only when STA is connected.
-
-setrxant
- This command is used to set the mode for Rx antenna.
-
- The options that can be sent are:-
- 1 -- Antenna 1.
- 2 -- Antenna 2.
- 0xFFFF -- Diversity.
-
- Usage:
- iwpriv ethX setrxant 0x01: select Antenna 1.
-
-getrxant
- This command is used to get the mode for Rx antenna.
-
-
-settxant
- This command is used to set the mode for Tx antenna.
- The options that can be sent are:-
- 1 -- Antenna 1.
- 2 -- Antenna 2.
- 0xFFFF -- Diversity.
- Usage:
- iwpriv ethX settxant 0x01: select Antenna 1.
-
-gettxant
- This command is used to get the mode for Tx antenna.
-
-authalgs
- This command is used by the WPA supplicant to set the authentication
- algorithms in the station.
-
-8021xauthalgs
- This command is used by the WPA supplicant to set the 8021.x authentication algorithm type
- station.
-
- where values can be:-
- 1 -- None
- 2 -- LEAP
- 4 -- TLS
- 8 -- TTLs
- 16 -- MD5
-
-
-encryptionmode
- This command is used by the WPA supplicant to set the encryption algorithm.
-
- where values can be:-
- 0 -- NONE
- 1 -- WEP40
- 2 -- TKIP
- 3 -- CCMP
- 4 -- WEP104
-
-pre-TBTT
- This command is used to set pre-TBTT time period where value is in microseconds.
-
setregioncode
This command is used to set the region code in the station.
where value is 'region code' for various regions like
@@ -270,114 +109,6 @@ getregioncode
This command is used to get the region code information set in the
station.
-setbcnavg
- Set the weighting factor for calculating RSSI.
-
-getbcnavg
- Get weighting factor for calculating RSSI.
-
-setdataavg
- Set the weighting factor for calculating SNR.
-
-setlisteninter
- This command is used to set the listen interval in the
- station.
-
- where the value ranges between 1 - 255
-
-getlisteninter
- This command is used to get the listen interval value set in the
- station.
-
-setmultipledtim
- This command is used to set the multiple dtim value in the
- station.
- where the value is 1,2,3,4,5,0xfffe
- 0xfffe means the firmware will use listen interval in association
- command for waking up
-
-getmultipledtim
- This command is used to get the multiple dtim value set in the station.
-
-atimwindow
- This command is used to set the atim value in the
- station.
-
- where the value ranges between 0 - 50
-
-deauth
- This command is used to send the de-authentication to the AP with which
- the station is associated. This command is valid only when
- station is in Infrastructure mode.
-
- Note: This command is available only when STA is connected.
-
-adhocstop
- This command is used to stop beacon transmission from the station and
- go into idle state in ad-hoc mode.
-
- Note: This command is available only when STA is connected.
-
-radioon
- This command is used to turn on the RF antenna.
-
-radiooff
- This command is sued to turn off the RF antenna.
-
-scanmode
- This command is used to set the station to scan for either IBSS
- networks or BSS networks or both BSS and IBSS networks. This
- command can be used with sub commands,
-
- where the value for
- bss -- Scan All the BSS networks.
- ibss -- Scan All the IBSS networks.
- any -- Scan both BSS and IBSS networks.
-
-
-
-setwpaie
- This command is used by WPA supplicant to send the WPA-IE to the driver.
-
-wlanidle-off
- This command is used to get into idle state.
-
- Note: This command is available only when STA is connected.
-
-wlanidle-on
- This command is used to get off the idle state.
-
- Note: This command is available only when STA is connected.
-
-
-getlog
- This command is used to get the 802.11 statistics available in the
- station.
-
- Note: This command is available only when STA is connected.
-
-getadhocstatus
- This command is used to get the ad-hoc Network Status.
-
- The various status codes are:
- AdhocStarted
- AdhocJoined
- AdhocIdle
- InfraMode
- AutoUnknownMode
-
- Note: This command is available only when STA is connected.
-
-adhocgrate
- This command is used to enable(1) g_rate, Disable(0) g_rate
- and request(2) the status which g_rate is disabled/enabled,
- for Ad-hoc creator.
-
- where value is:-
- 0 -- Disabled
- 1 -- Enabled
- 2 -- Get
-
ledgpio
This command is used to set/get LEDs.
@@ -400,253 +131,6 @@ ledgpio
Note: LED0 is invalid
Note: Maximum Number of LEDs are 16.
-inactivityto
- This command is used by the host to set/get the inactivity timeout value,
- which specifies when WLAN device is put to sleep.
-
- Usage:
- iwpriv ethX inactivityto [<timeout>]
-
- where the parameter are:
- timeout: timeout value in milliseconds.
-
- Example:
- iwpriv eth1 inactivityto
- "get the timeout value"
-
- iwpriv eth1 inactivityto X
- "set timeout value to X ms"
-
-
-sleeppd
- This command is used to configure the sleep period of the WLAN device.
-
- Usage:
- iwpriv ethX sleeppd [<sleep period>]
-
- where the parameter are:
- Period: sleep period in milliseconds. Range 10~60.
-
- Example:
- iwpriv eth1 sleeppd 10
- "set period as 10 ms"
- iwpriv eth1 sleeppd
- "get the sleep period configuration"
-
-enable11d
- This command is used to control 11d
- where value is:-
- 1 -- Enabled
- 0 -- Disabled
- 2 -- Get
-
-
-
-
-tpccfg
- Enables or disables automatic transmit power control.
-
- The first parameter turns this feature on (1) or off (0). When turning
- on, the user must also supply four more parameters in the following
- order:
- -UseSNR (Use SNR (in addition to PER) for TPC algorithm),
- -P0 (P0 power level for TPC),
- -P1 (P1 power level for TPC),
- -P2 (P2 power level for TPC).
-
- Usage:
- iwpriv ethX tpccfg: Get current configuration
- iwpriv ethX tpccfg 0: disable auto TPC
- iwpriv ethX tpccfg 0x01 0x00 0x05 0x0a 0x0d: enable auto TPC; do not use SNR;
- P0=0x05; P1=0x0a; P2=0x0d;
- iwpriv ethX tpccfg 0x01 0x01 0x05 0x0a 0x0d: enable auto TPC; use SNR;
- P0=0x05; P1=0x0a; P2=0x0d.
-
-powercfg
- Enables or disables power adaptation.
-
- The first parameter turns this feature on (1) or off (0). When turning
- on, the user must also supply three more parameters in the following
- order:
- -P0 (P0 power level for Power Adaptation),
- -P1 (P1 power level for Power Adaptation),
- -P2 (P2 power level for Power Adaptation).
-
- Usage:
- iwpriv ethX powercfg: Get current configuration
- iwpriv ethX powercfg 0: disable power adaptation
- iwpriv ethX powercfg 1 0x0d 0x0f 0x12: enable power adaptation;
- P0=0x0d; P1=0x0f; P2=0x12.
-
-getafc
- This command returns automatic frequency control parameters. It returns
- three integers:
- -P0: automatic is on (1), or off (0),
- -P1: current timing offset in PPM (part per million), and
- -P2: current frequency offset in PPM.
-
-setafc
- Set automatic frequency control options.
-
- The first parameter turns automatic on (1) or off (0).
- The user must supply two more parameters in either case, in the following
- order:
-
- When auto is on:
-
- -P0 (automatic adjustment frequency threshold in PPM),
- -P1 (automatic adjustment period in beacon period),
-
- When auto is off:
-
- -P0 (manual adjustment timing offset in PPM), and
- -P1 (manual adjustment frequency offset in PPM).
-
- Usage:
- iwpriv ethX setafc 0 10 10: manual adjustment, both timing and frequcncy
- offset are 10 PPM.
-
- iwpriv ethX setafc 1 10 10 enable afc, automatic adjustment,
- frequency threshold 10 PPM, for every 10 beacon periods.
-
-
-
-scanprobes
- This command sets number of probe requests per channel.
-
- Usage:
- iwpriv ethX scanprobes 3 (set scan probes to 3)
- iwpriv ethX scanprobes (get scan probes)
-
-lolisteninter
- This command sets the value of listen interval.
-
- Usage:
- iwpriv ethX lolisteninter 234 (set the lolisteninter to 234)
- iwpriv ethX lolisteninter (get the lolisteninter value)
-
-rateadapt
- This command sets the data rates bitmap.
- Where <n>
- 0: Disable auto rate adapt
- 1: Enable auto rate adapt
-
- <m>
- data rate bitmap
- Bit Data rate
- 0 1 Mbps
- 1 2 Mbps
- 2 5.5 Mbps
- 3 11 Mbps
- 4 Reserved
- 5 6 Mbps
- 6 9 Mbps
- 7 12 Mbps
- 8 18 Mbps
- 9 24 Mbps
- 10 36 Mbps
- 11 48 Mbps
- 12 54 Mbps
- 12-15 Reserved
-
- Usage:
- iwpriv ethX rateadapt
- read the currect data rate setting
- iwpriv ethX rateadapt 1 0x07
- enable auto data rate adapt and
- data rates are 1Mbps, 2Mbsp and 5.5Mbps
-
-
-txcontrol
- This command is used to set the Tx rate, ack policy, and retry limit on a per packet basis.
-
- Where value <n> is:
- if bit[4] == 1:
- bit[3:0] -- 0 1 2 3 4 5 6 7 8 9 10 11 12 13-16
- Data Rate(Mbps) -- 1 2 5.5 11 Rsv 6 9 12 18 24 36 48 54 Rsv
-
- bit[12:8]
- if bit[12] == 1, bit[11:8] specifies the Tx retry limit.
-
- bit[14:13] specifies per packet ack policy:
- bit[14:13]
- 1 0 use immediate ack policy for this packet
- 1 1 use no ack policy for this packet
- 0 x use the per-packet ack policy setting
-
- Usage:
- iwpriv ethX txcontrol 0x7513
- Use no-ack policy, 5 retires for Tx, 11Mbps rate
-
-
-
-psnullinterval
- This command is used to set/request NULL package interval for Power Save
- under infrastructure mode.
-
- where value is:-
- -1 -- Disabled
- n>0 -- Set interval as n (seconds)
-
-prescan
- This command is used to enable (1)/disable(0) auto prescan before assoicate to the ap
-
- where value is:-
- 0 -- Disabled
- 1 -- Enabled
- 2 -- Get
-
-getrxinfo
- This command gets non average value of Signal to Noise Ratio of Data and rate index.
-
- The following table shows RateIndex and Rate
-
- RateIndex Data rate
- 0 1 Mbps
- 1 2 Mbps
- 2 5.5 Mbps
- 3 11 Mbps
- 4 Reserved
- 5 6 Mbps
- 6 9 Mbps
- 7 12 Mbps
- 8 18 Mbps
- 9 24 Mbps
- 10 36 Mbps
- 11 48 Mbps
- 12 54 Mbps
- 13-15 Reserved
-
-gettxrate
- This command gets current Tx rate index of the first packet associated with Rate Adaptation.
-
- The following table shows RateIndex and Rate
-
- RateIndex Data rate
- 0 1 Mbps
- 1 2 Mbps
- 2 5.5 Mbps
- 3 11 Mbps
- 4 Reserved
- 5 6 Mbps
- 6 9 Mbps
- 7 12 Mbps
- 8 18 Mbps
- 9 24 Mbps
- 10 36 Mbps
- 11 48 Mbps
- 12 54 Mbps
- 13-15 Reserved
-
-bcninterval
- This command is used to sets beacon interval in adhoc mode when an argument is given, and gets current adhoc
- beacon interval when no argument is given. The valid beacon interval is between 20 - 1000,
- default beacon interval is 100.
-
- Usage:
- iwpriv ethX bcninterval 100 (set adhoc beacon interval to 100)
- iwpriv ethX bcninterval (get adhoc beacon interval)
-
fwt_add
This command is used to insert an entry into the FWT table. The list of
parameters must follow the following structure:
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index b55c7f57aca..c260bd1b3d4 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -23,13 +23,13 @@ static int assoc_helper_essid(wlan_private *priv,
ENTER();
lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid);
- if (assoc_req->mode == wlan802_11infrastructure) {
+ if (assoc_req->mode == IW_MODE_INFRA) {
if (adapter->prescan) {
libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1);
}
i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid,
- NULL, wlan802_11infrastructure);
+ NULL, IW_MODE_INFRA);
if (i >= 0) {
lbs_pr_debug(1,
"SSID found in scan list ... associating...\n");
@@ -44,7 +44,7 @@ static int assoc_helper_essid(wlan_private *priv,
lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n",
assoc_req->ssid.ssid);
}
- } else if (assoc_req->mode == wlan802_11ibss) {
+ } else if (assoc_req->mode == IW_MODE_ADHOC) {
/* Scan for the network, do not save previous results. Stale
* scan data will cause us to join a non-existant adhoc network
*/
@@ -52,7 +52,7 @@ static int assoc_helper_essid(wlan_private *priv,
/* Search for the requested SSID in the scan table */
i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL,
- wlan802_11ibss);
+ IW_MODE_ADHOC);
if (i >= 0) {
lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret);
libertas_join_adhoc_network(priv, &adapter->scantable[i]);
@@ -90,10 +90,10 @@ static int assoc_helper_bssid(wlan_private *priv,
goto out;
}
- if (assoc_req->mode == wlan802_11infrastructure) {
+ if (assoc_req->mode == IW_MODE_INFRA) {
ret = wlan_associate(priv, &adapter->scantable[i]);
lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret);
- } else if (assoc_req->mode == wlan802_11ibss) {
+ } else if (assoc_req->mode == IW_MODE_ADHOC) {
libertas_join_adhoc_network(priv, &adapter->scantable[i]);
}
memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid,
@@ -142,23 +142,23 @@ static int assoc_helper_mode(wlan_private *priv,
ENTER();
- if (assoc_req->mode == adapter->inframode) {
+ if (assoc_req->mode == adapter->mode) {
LEAVE();
return 0;
}
- if (assoc_req->mode == wlan802_11infrastructure) {
+ if (assoc_req->mode == IW_MODE_INFRA) {
if (adapter->psstate != PS_STATE_FULL_POWER)
libertas_ps_wakeup(priv, cmd_option_waitforrsp);
adapter->psmode = wlan802_11powermodecam;
}
- adapter->inframode = assoc_req->mode;
+ adapter->mode = assoc_req->mode;
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_snmp_mib,
0, cmd_option_waitforrsp,
OID_802_11_INFRASTRUCTURE_MODE,
- (void *) assoc_req->mode);
+ (void *) (size_t) assoc_req->mode);
LEAVE();
return ret;
@@ -196,7 +196,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
goto out;
/* enable/disable the MAC's WEP packet filter */
- if (assoc_req->secinfo.WEPstatus == wlan802_11WEPenabled)
+ if (assoc_req->secinfo.wep_enabled)
adapter->currentpacketfilter |= cmd_act_mac_wep_enable;
else
adapter->currentpacketfilter &= ~cmd_act_mac_wep_enable;
@@ -300,8 +300,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
}
if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
- if (adapter->secinfo.authmode !=
- assoc_req->secinfo.authmode) {
+ if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
lbs_pr_debug(1, "Deauthenticating due to updated security "
"info in configuration request.\n");
return 1;
@@ -316,7 +315,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
/* FIXME: deal with 'auto' mode somehow */
if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
- if (assoc_req->mode != wlan802_11infrastructure)
+ if (assoc_req->mode != IW_MODE_INFRA)
return 1;
}
@@ -333,12 +332,12 @@ static int should_stop_adhoc(wlan_adapter *adapter,
if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength)
return 1;
if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid,
- sizeof(struct WLAN_802_11_SSID)))
+ adapter->curbssparams.ssid.ssidlength))
return 1;
/* FIXME: deal with 'auto' mode somehow */
if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
- if (assoc_req->mode != wlan802_11ibss)
+ if (assoc_req->mode != IW_MODE_ADHOC)
return 1;
}
@@ -382,7 +381,7 @@ void wlan_association_worker(struct work_struct *work)
}
if (find_any_ssid) {
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
+ u8 new_mode;
ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid,
assoc_req->mode, &new_mode);
@@ -393,7 +392,7 @@ void wlan_association_worker(struct work_struct *work)
}
/* Ensure we switch to the mode of the AP */
- if (assoc_req->mode == wlan802_11autounknown) {
+ if (assoc_req->mode == IW_MODE_AUTO) {
set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
assoc_req->mode = new_mode;
}
@@ -403,7 +402,7 @@ void wlan_association_worker(struct work_struct *work)
* Check if the attributes being changing require deauthentication
* from the currently associated infrastructure access point.
*/
- if (adapter->inframode == wlan802_11infrastructure) {
+ if (adapter->mode == IW_MODE_INFRA) {
if (should_deauth_infrastructure(adapter, assoc_req)) {
ret = libertas_send_deauthentication(priv);
if (ret) {
@@ -412,7 +411,7 @@ void wlan_association_worker(struct work_struct *work)
ret);
}
}
- } else if (adapter->inframode == wlan802_11ibss) {
+ } else if (adapter->mode == IW_MODE_ADHOC) {
if (should_stop_adhoc(adapter, assoc_req)) {
ret = libertas_stop_adhoc_network(priv);
if (ret) {
@@ -543,7 +542,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
assoc_req->channel = adapter->curbssparams.channel;
if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
- assoc_req->mode = adapter->inframode;
+ assoc_req->mode = adapter->mode;
if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
memcpy(&assoc_req->bssid, adapter->curbssparams.bssid,
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index bfdac58b5c0..de9cb46a70f 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -381,15 +381,16 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
switch (cmd_oid) {
case OID_802_11_INFRASTRUCTURE_MODE:
{
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode =
- (enum WLAN_802_11_NETWORK_INFRASTRUCTURE) pdata_buf;
+ u8 mode = (u8) (size_t) pdata_buf;
pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
pSNMPMIB->oid = cpu_to_le16((u16) desired_bsstype_i);
pSNMPMIB->bufsize = sizeof(u8);
- if (mode == wlan802_11infrastructure)
- ucTemp = SNMP_MIB_VALUE_INFRA;
- else
+ if (mode == IW_MODE_ADHOC) {
ucTemp = SNMP_MIB_VALUE_ADHOC;
+ } else {
+ /* Infra and Auto modes */
+ ucTemp = SNMP_MIB_VALUE_INFRA;
+ }
memmove(pSNMPMIB->value, &ucTemp, sizeof(u8));
@@ -947,8 +948,8 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
spin_unlock_irqrestore(&adapter->driver_lock, flags);
- lbs_pr_debug(1, "QUEUE_CMD: Inserted node=0x%x, cmd=0x%x in cmdpendingq\n",
- (u32) cmdnode,
+ lbs_pr_debug(1, "QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
+ cmdnode,
((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command);
done:
@@ -976,8 +977,8 @@ static int DownloadcommandToStation(wlan_private * priv,
ENTER();
if (!adapter || !cmdnode) {
- lbs_pr_debug(1, "DNLD_CMD: adapter = %#x, cmdnode = %#x\n",
- (int)adapter, (int)cmdnode);
+ lbs_pr_debug(1, "DNLD_CMD: adapter = %p, cmdnode = %p\n",
+ adapter, cmdnode);
if (cmdnode) {
spin_lock_irqsave(&adapter->driver_lock, flags);
__libertas_cleanup_and_insert_cmd(priv, cmdnode);
@@ -1174,8 +1175,8 @@ int libertas_prepare_and_send_command(wlan_private * priv,
cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
- lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr =0x%x, command=0x%X\n",
- (u32) cmdptr, cmd_no);
+ lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
+ cmdptr, cmd_no);
if (!cmdptr) {
lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index cdb012c7e9c..c86454034b5 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -72,8 +72,6 @@ void libertas_mac_event_disconnected(wlan_private * priv)
adapter->secinfo.WPAenabled = 0;
adapter->secinfo.WPA2enabled = 0;
adapter->wpa_ie_len = 0;
- adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
- adapter->secinfo.Encryptionmode = CIPHER_NONE;
adapter->connect_status = libertas_disconnected;
@@ -811,7 +809,7 @@ int libertas_process_rx_command(wlan_private * priv)
if (result) {
lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n",
resp->result);
- if (adapter->inframode == wlan802_11ibss) {
+ if (adapter->mode == IW_MODE_ADHOC) {
/*
* We should not re-try enter-ps command in
* ad-hoc mode. It takes place in
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 51dfd202f55..7d7bc5e86a5 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -7,6 +7,7 @@
#include "dev.h"
#include "decl.h"
#include "host.h"
+#include "debugfs.h"
static struct dentry *libertas_dir = NULL;
static char *szStates[] = {
@@ -276,7 +277,7 @@ static void libertas_parse_ssid(char *buf, size_t count,
if (!end)
end = buf + count - 1;
- size = min(IW_ESSID_MAX_SIZE, end - hold);
+ size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
strncpy(scan_cfg->specificSSID, hold, size);
return;
@@ -1648,7 +1649,7 @@ struct libertas_debugfs_files {
struct file_operations fops;
};
-struct libertas_debugfs_files debugfs_files[] = {
+static struct libertas_debugfs_files debugfs_files[] = {
{ "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
{ "getscantable", 0444, FOPS(libertas_getscantable,
write_file_dummy), },
@@ -1658,7 +1659,7 @@ struct libertas_debugfs_files debugfs_files[] = {
{ "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
};
-struct libertas_debugfs_files debugfs_events_files[] = {
+static struct libertas_debugfs_files debugfs_events_files[] = {
{"low_rssi", 0644, FOPS(libertas_lowrssi_read,
libertas_lowrssi_write), },
{"low_snr", 0644, FOPS(libertas_lowsnr_read,
@@ -1673,7 +1674,7 @@ struct libertas_debugfs_files debugfs_events_files[] = {
libertas_highsnr_write), },
};
-struct libertas_debugfs_files debugfs_regs_files[] = {
+static struct libertas_debugfs_files debugfs_regs_files[] = {
{"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
{"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
{"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
@@ -1778,7 +1779,7 @@ void libertas_debugfs_remove_one(wlan_private *priv)
struct debug_data {
char name[32];
u32 size;
- u32 addr;
+ size_t addr;
};
/* To debug any member of wlan_adapter, simply add one line here.
@@ -1825,6 +1826,8 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
val = *((u16 *) d[i].addr);
else if (d[i].size == 4)
val = *((u32 *) d[i].addr);
+ else if (d[i].size == 8)
+ val = *((u64 *) d[i].addr);
pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
}
@@ -1844,7 +1847,7 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
* @param data data to write
* @return number of data
*/
-static int wlan_debugfs_write(struct file *f, const char __user *buf,
+static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
size_t cnt, loff_t *ppos)
{
int r, i;
@@ -1886,12 +1889,14 @@ static int wlan_debugfs_write(struct file *f, const char __user *buf,
*((u16 *) d[i].addr) = (u16) r;
else if (d[i].size == 4)
*((u32 *) d[i].addr) = (u32) r;
+ else if (d[i].size == 8)
+ *((u64 *) d[i].addr) = (u64) r;
break;
} while (1);
}
kfree(pdata);
- return cnt;
+ return (ssize_t)cnt;
}
static struct file_operations libertas_debug_fops = {
@@ -1916,20 +1921,10 @@ void libertas_debug_init(wlan_private * priv, struct net_device *dev)
return;
for (i = 0; i < num_of_items; i++)
- items[i].addr += (u32) priv->adapter;
+ items[i].addr += (size_t) priv->adapter;
priv->debugfs_debug = debugfs_create_file("debug", 0644,
priv->debugfs_dir, &items[0],
&libertas_debug_fops);
}
-/**
- * @brief remove proc file
- *
- * @param priv pointer wlan_private
- * @return N/A
- */
-void libertas_debug_remove(wlan_private * priv)
-{
- debugfs_remove(priv->debugfs_debug);
-}
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index fb1478c1b87..80dd9ea19c8 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -9,6 +9,11 @@
extern unsigned int libertas_debug;
+#ifdef CONFIG_LIBERTAS_DEBUG
+#define DEBUG
+#define PROC_DEBUG
+#endif
+
#define DRV_NAME "usb8xxx"
#define lbs_pr_info(format, args...) \
@@ -223,31 +228,6 @@ enum SNRNF_DATA {
MAX_TYPE_AVG
};
-/** WLAN_802_11_AUTH_ALG*/
-enum WLAN_802_11_AUTH_ALG {
- AUTH_ALG_OPEN_SYSTEM = 1,
- AUTH_ALG_SHARED_KEY = 2,
- AUTH_ALG_NETWORK_EAP = 8,
-};
-
-/** WLAN_802_1X_AUTH_ALG */
-enum WLAN_802_1X_AUTH_ALG {
- WLAN_1X_AUTH_ALG_NONE = 1,
- WLAN_1X_AUTH_ALG_LEAP = 2,
- WLAN_1X_AUTH_ALG_TLS = 4,
- WLAN_1X_AUTH_ALG_TTLS = 8,
- WLAN_1X_AUTH_ALG_MD5 = 16,
-};
-
-/** WLAN_802_11_ENCRYPTION_MODE */
-enum WLAN_802_11_ENCRYPTION_MODE {
- CIPHER_NONE,
- CIPHER_WEP40,
- CIPHER_TKIP,
- CIPHER_CCMP,
- CIPHER_WEP104,
-};
-
/** WLAN_802_11_POWER_MODE */
enum WLAN_802_11_POWER_MODE {
wlan802_11powermodecam,
@@ -292,28 +272,6 @@ enum mv_ms_type {
MVMS_EVENT
};
-/** WLAN_802_11_NETWORK_INFRASTRUCTURE */
-enum WLAN_802_11_NETWORK_INFRASTRUCTURE {
- wlan802_11ibss,
- wlan802_11infrastructure,
- wlan802_11autounknown,
- /*defined as upper bound */
- wlan802_11infrastructuremax
-};
-
-/** WLAN_802_11_AUTHENTICATION_MODE */
-enum WLAN_802_11_AUTHENTICATION_MODE {
- wlan802_11authmodeopen = 0x00,
- wlan802_11authmodeshared = 0x01,
- wlan802_11authmodenetworkEAP = 0x80,
-};
-
-/** WLAN_802_11_WEP_STATUS */
-enum WLAN_802_11_WEP_STATUS {
- wlan802_11WEPenabled,
- wlan802_11WEPdisabled,
-};
-
/** SNMP_MIB_INDEX_e */
enum SNMP_MIB_INDEX_e {
desired_bsstype_i = 0,
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index b1f876f9693..e8b9020f9bd 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -10,6 +10,7 @@
#include <linux/wireless.h>
#include <linux/ethtool.h>
#include <linux/debugfs.h>
+#include <net/ieee80211.h>
#include "defs.h"
#include "scan.h"
@@ -56,10 +57,8 @@ struct region_channel {
struct wlan_802_11_security {
u8 WPAenabled;
u8 WPA2enabled;
- enum WLAN_802_11_WEP_STATUS WEPstatus;
- enum WLAN_802_11_AUTHENTICATION_MODE authmode;
- enum WLAN_802_1X_AUTH_ALG auth1xalg;
- enum WLAN_802_11_ENCRYPTION_MODE Encryptionmode;
+ u8 wep_enabled;
+ u8 auth_mode;
};
/** Current Basic Service Set State Structure */
@@ -184,7 +183,7 @@ struct assoc_request {
struct WLAN_802_11_SSID ssid;
u8 channel;
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode;
+ u8 mode;
u8 bssid[ETH_ALEN];
/** WEP keys */
@@ -198,7 +197,6 @@ struct assoc_request {
struct wlan_802_11_security secinfo;
/** WPA Information Elements*/
-#define MAX_WPA_IE_LEN 64
u8 wpa_ie[MAX_WPA_IE_LEN];
u8 wpa_ie_len;
};
@@ -254,7 +252,8 @@ struct _wlan_adapter {
/** current ssid/bssid related parameters*/
struct current_bss_params curbssparams;
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
+ /* IW_MODE_* */
+ u8 mode;
struct bss_descriptor *pattemptedbssdesc;
@@ -339,7 +338,6 @@ struct _wlan_adapter {
struct WLAN_802_11_KEY wpa_unicast_key;
/** WPA Information Elements*/
-#define MAX_WPA_IE_LEN 64
u8 wpa_ie[MAX_WPA_IE_LEN];
u8 wpa_ie_len;
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index b194a457079..441123c85e6 100644
--- a/drivers/net/wireless/libertas/fw.c
+++ b/drivers/net/wireless/libertas/fw.c
@@ -194,16 +194,13 @@ static void wlan_init_adapter(wlan_private * priv)
adapter->scanmode = cmd_bss_type_any;
/* 802.11 specific */
- adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
+ adapter->secinfo.wep_enabled = 0;
for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
i++)
memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY));
adapter->wep_tx_keyidx = 0;
- adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
- adapter->secinfo.authmode = wlan802_11authmodeopen;
- adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
- adapter->secinfo.Encryptionmode = CIPHER_NONE;
- adapter->inframode = wlan802_11infrastructure;
+ adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
+ adapter->mode = IW_MODE_INFRA;
adapter->assoc_req = NULL;
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 695fb6a66ff..ae6f72a6cdf 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -388,7 +388,7 @@ static int __if_usb_submit_rx_urb(wlan_private * priv,
usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
usb_rcvbulkpipe(cardp->udev,
cardp->bulk_in_endpointAddr),
- skb->tail + IPFIELD_ALIGN_OFFSET,
+ (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
rinfo);
@@ -626,6 +626,7 @@ static void if_usb_receive(struct urb *urb)
cardp->usb_event_cause);
if (cardp->usb_event_cause & 0xffff0000) {
libertas_send_tx_feedback(priv);
+ spin_unlock(&priv->adapter->driver_lock);
break;
}
cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3;
@@ -775,7 +776,6 @@ restart:
return -1;
}
-#ifdef SUPPORT_BOOT_COMMAND
cardp->bootcmdresp = 0;
do {
int j = 0;
@@ -796,7 +796,6 @@ restart:
}
return -1;
}
-#endif
i = 0;
priv->adapter->fw_ready = 0;
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index 785116720bc..170dfe6809f 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -12,7 +12,6 @@
#define USB8388_VID_2 0x05a3
#define USB8388_PID_2 0x8388
-#ifdef SUPPORT_BOOT_COMMAND
#define BOOT_CMD_FW_BY_USB 0x01
#define BOOT_CMD_FW_IN_EEPROM 0x02
#define BOOT_CMD_UPDATE_BOOT2 0x03
@@ -36,7 +35,6 @@ struct bootcmdrespStr
u8 u8result;
u8 au8dumy[2];
};
-#endif /* SUPPORT_BOOT_COMMAND */
/* read callback private data */
struct read_cb_info {
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
index 82b39642423..a8f76c35899 100644
--- a/drivers/net/wireless/libertas/ioctl.c
+++ b/drivers/net/wireless/libertas/ioctl.c
@@ -27,95 +27,6 @@
#define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)
-static int setrxantenna(wlan_private * priv, int mode)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
-
- if (mode != RF_ANTENNA_1 && mode != RF_ANTENNA_2
- && mode != RF_ANTENNA_AUTO) {
- return -EINVAL;
- }
-
- adapter->rxantennamode = mode;
-
- lbs_pr_debug(1, "SET RX Antenna mode to 0x%04x\n", adapter->rxantennamode);
-
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
- cmd_act_set_rx,
- cmd_option_waitforrsp, 0,
- &adapter->rxantennamode);
- return ret;
-}
-
-static int settxantenna(wlan_private * priv, int mode)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
-
- if ((mode != RF_ANTENNA_1) && (mode != RF_ANTENNA_2)
- && (mode != RF_ANTENNA_AUTO)) {
- return -EINVAL;
- }
-
- adapter->txantennamode = mode;
-
- lbs_pr_debug(1, "SET TX Antenna mode to 0x%04x\n", adapter->txantennamode);
-
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
- cmd_act_set_tx,
- cmd_option_waitforrsp, 0,
- &adapter->txantennamode);
-
- return ret;
-}
-
-static int getrxantenna(wlan_private * priv, char *buf)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
-
- // clear it, so we will know if the value
- // returned below is correct or not.
- adapter->rxantennamode = 0;
-
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
- cmd_act_get_rx,
- cmd_option_waitforrsp, 0, NULL);
-
- if (ret) {
- LEAVE();
- return ret;
- }
-
- lbs_pr_debug(1, "Get Rx Antenna mode:0x%04x\n", adapter->rxantennamode);
-
- return sprintf(buf, "0x%04x", adapter->rxantennamode) + 1;
-}
-
-static int gettxantenna(wlan_private * priv, char *buf)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
-
- // clear it, so we will know if the value
- // returned below is correct or not.
- adapter->txantennamode = 0;
-
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
- cmd_act_get_tx,
- cmd_option_waitforrsp, 0, NULL);
-
- if (ret) {
- LEAVE();
- return ret;
- }
-
- lbs_pr_debug(1, "Get Tx Antenna mode:0x%04x\n", adapter->txantennamode);
-
- return sprintf(buf, "0x%04x", adapter->txantennamode) + 1;
-}
-
static int wlan_set_region(wlan_private * priv, u16 region_code)
{
int i;
@@ -144,998 +55,6 @@ static int wlan_set_region(wlan_private * priv, u16 region_code)
return 0;
}
-/**
- * @brief Get/Set Firmware wakeup method
- *
- * @param priv A pointer to wlan_private structure
- * @param wrq A pointer to user data
- * @return 0--success, otherwise fail
- */
-static int wlan_txcontrol(wlan_private * priv, struct iwreq *wrq)
-{
- wlan_adapter *adapter = priv->adapter;
- int data;
- ENTER();
-
- if ((int)wrq->u.data.length == 0) {
- if (copy_to_user
- (wrq->u.data.pointer, &adapter->pkttxctrl, sizeof(u32))) {
- lbs_pr_alert("copy_to_user failed!\n");
- return -EFAULT;
- }
- } else {
- if ((int)wrq->u.data.length > 1) {
- lbs_pr_alert("ioctl too many args!\n");
- return -EFAULT;
- }
- if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
- lbs_pr_alert("Copy from user failed\n");
- return -EFAULT;
- }
-
- adapter->pkttxctrl = (u32) data;
- }
-
- wrq->u.data.length = 1;
-
- LEAVE();
- return 0;
-}
-
-/**
- * @brief Get/Set NULL Package generation interval
- *
- * @param priv A pointer to wlan_private structure
- * @param wrq A pointer to user data
- * @return 0--success, otherwise fail
- */
-static int wlan_null_pkt_interval(wlan_private * priv, struct iwreq *wrq)
-{
- wlan_adapter *adapter = priv->adapter;
- int data;
- ENTER();
-
- if ((int)wrq->u.data.length == 0) {
- data = adapter->nullpktinterval;
-
- if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
- lbs_pr_alert( "copy_to_user failed!\n");
- return -EFAULT;
- }
- } else {
- if ((int)wrq->u.data.length > 1) {
- lbs_pr_alert( "ioctl too many args!\n");
- return -EFAULT;
- }
- if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
-
- adapter->nullpktinterval = data;
- }
-
- wrq->u.data.length = 1;
-
- LEAVE();
- return 0;
-}
-
-static int wlan_get_rxinfo(wlan_private * priv, struct iwreq *wrq)
-{
- wlan_adapter *adapter = priv->adapter;
- int data[2];
- ENTER();
- data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
- data[1] = adapter->rxpd_rate;
- if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
- wrq->u.data.length = 2;
- LEAVE();
- return 0;
-}
-
-static int wlan_get_snr(wlan_private * priv, struct iwreq *wrq)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
- int data[4];
-
- ENTER();
- memset(data, 0, sizeof(data));
- if (wrq->u.data.length) {
- if (copy_from_user(data, wrq->u.data.pointer,
- min_t(size_t, wrq->u.data.length, 4) * sizeof(int)))
- return -EFAULT;
- }
- if ((wrq->u.data.length == 0) || (data[0] == 0) || (data[0] == 1)) {
- if (adapter->connect_status == libertas_connected) {
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_rssi,
- 0,
- cmd_option_waitforrsp,
- 0, NULL);
-
- if (ret) {
- LEAVE();
- return ret;
- }
- }
- }
-
- if (wrq->u.data.length == 0) {
- data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
- data[1] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
- data[2] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
- data[3] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
- if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 4))
- return -EFAULT;
- wrq->u.data.length = 4;
- } else if (data[0] == 0) {
- data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
- if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
- return -EFAULT;
- wrq->u.data.length = 1;
- } else if (data[0] == 1) {
- data[0] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
- if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
- return -EFAULT;
- wrq->u.data.length = 1;
- } else if (data[0] == 2) {
- data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
- if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
- return -EFAULT;
- wrq->u.data.length = 1;
- } else if (data[0] == 3) {
- data[0] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
- if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
- return -EFAULT;
- wrq->u.data.length = 1;
- } else
- return -ENOTSUPP;
-
- LEAVE();
- return 0;
-}
-
-static int wlan_beacon_interval(wlan_private * priv, struct iwreq *wrq)
-{
- int data;
- wlan_adapter *adapter = priv->adapter;
-
- if (wrq->u.data.length > 0) {
- if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int)))
- return -EFAULT;
-
- lbs_pr_debug(1, "WLAN SET BEACON INTERVAL: %d\n", data);
- if ((data > MRVDRV_MAX_BEACON_INTERVAL)
- || (data < MRVDRV_MIN_BEACON_INTERVAL))
- return -ENOTSUPP;
- adapter->beaconperiod = data;
- }
- data = adapter->beaconperiod;
- if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int)))
- return -EFAULT;
-
- wrq->u.data.length = 1;
-
- return 0;
-}
-
-static int wlan_get_rssi(wlan_private * priv, struct iwreq *wrq)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
- int temp;
- int data = 0;
- int *val;
-
- ENTER();
- data = SUBCMD_DATA(wrq);
- if ((data == 0) || (data == 1)) {
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_rssi,
- 0, cmd_option_waitforrsp,
- 0, NULL);
- if (ret) {
- LEAVE();
- return ret;
- }
- }
-
- switch (data) {
- case 0:
-
- temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
- adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
- break;
- case 1:
- temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG],
- adapter->NF[TYPE_BEACON][TYPE_AVG]);
- break;
- case 2:
- temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
- adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
- break;
- case 3:
- temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
- adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
- break;
- default:
- return -ENOTSUPP;
- }
- val = (int *)wrq->u.name;
- *val = temp;
-
- LEAVE();
- return 0;
-}
-
-static int wlan_get_nf(wlan_private * priv, struct iwreq *wrq)
-{
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
- int temp;
- int data = 0;
- int *val;
-
- data = SUBCMD_DATA(wrq);
- if ((data == 0) || (data == 1)) {
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_rssi,
- 0, cmd_option_waitforrsp,
- 0, NULL);
-
- if (ret) {
- LEAVE();
- return ret;
- }
- }
-
- switch (data) {
- case 0:
- temp = adapter->NF[TYPE_BEACON][TYPE_NOAVG];
- break;
- case 1:
- temp = adapter->NF[TYPE_BEACON][TYPE_AVG];
- break;
- case 2:
- temp = adapter->NF[TYPE_RXPD][TYPE_NOAVG];
- break;
- case 3:
- temp = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
- break;
- default:
- return -ENOTSUPP;
- }
-
- temp = CAL_NF(temp);
-
- lbs_pr_debug(1, "%s: temp = %d\n", __FUNCTION__, temp);
- val = (int *)wrq->u.name;
- *val = temp;
- return 0;
-}
-
-static int wlan_get_txrate_ioctl(wlan_private * priv, struct ifreq *req)
-{
- wlan_adapter *adapter = priv->adapter;
- int *pdata;
- struct iwreq *wrq = (struct iwreq *)req;
- int ret = 0;
- adapter->txrate = 0;
- lbs_pr_debug(1, "wlan_get_txrate_ioctl\n");
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_tx_rate_query,
- cmd_act_get, cmd_option_waitforrsp,
- 0, NULL);
- if (ret)
- return ret;
-
- pdata = (int *)wrq->u.name;
- *pdata = (int)adapter->txrate;
- return 0;
-}
-
-static int wlan_get_adhoc_status_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
- char status[64];
- wlan_adapter *adapter = priv->adapter;
-
- memset(status, 0, sizeof(status));
-
- switch (adapter->inframode) {
- case wlan802_11ibss:
- if (adapter->connect_status == libertas_connected) {
- if (adapter->adhoccreate)
- memcpy(&status, "AdhocStarted", sizeof(status));
- else
- memcpy(&status, "AdhocJoined", sizeof(status));
- } else {
- memcpy(&status, "AdhocIdle", sizeof(status));
- }
- break;
- case wlan802_11infrastructure:
- memcpy(&status, "Inframode", sizeof(status));
- break;
- default:
- memcpy(&status, "AutoUnknownmode", sizeof(status));
- break;
- }
-
- lbs_pr_debug(1, "status = %s\n", status);
- wrq->u.data.length = strlen(status) + 1;
-
- if (wrq->u.data.pointer) {
- if (copy_to_user(wrq->u.data.pointer,
- &status, wrq->u.data.length))
- return -EFAULT;
- }
-
- LEAVE();
- return 0;
-}
-
-/**
- * @brief Set/Get WPA IE
- * @param priv A pointer to wlan_private structure
- * @param req A pointer to ifreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_setwpaie_ioctl(wlan_private * priv, struct ifreq *req)
-{
- struct iwreq *wrq = (struct iwreq *)req;
- wlan_adapter *adapter = priv->adapter;
- int ret = 0;
-
- ENTER();
-
- if (wrq->u.data.length) {
- if (wrq->u.data.length > sizeof(adapter->wpa_ie)) {
- lbs_pr_debug(1, "failed to copy WPA IE, too big \n");
- return -EFAULT;
- }
- if (copy_from_user(adapter->wpa_ie, wrq->u.data.pointer,
- wrq->u.data.length)) {
- lbs_pr_debug(1, "failed to copy WPA IE \n");
- return -EFAULT;
- }
- adapter->wpa_ie_len = wrq->u.data.length;
- lbs_pr_debug(1, "Set wpa_ie_len=%d IE=%#x\n", adapter->wpa_ie_len,
- adapter->wpa_ie[0]);
- lbs_dbg_hex("wpa_ie", adapter->wpa_ie, adapter->wpa_ie_len);
- if (adapter->wpa_ie[0] == WPA_IE)
- adapter->secinfo.WPAenabled = 1;
- else if (adapter->wpa_ie[0] == WPA2_IE)
- adapter->secinfo.WPA2enabled = 1;
- else {
- adapter->secinfo.WPAenabled = 0;
- adapter->secinfo.WPA2enabled = 0;
- }
- } else {
- memset(adapter->wpa_ie, 0, sizeof(adapter->wpa_ie));
- adapter->wpa_ie_len = wrq->u.data.length;
- lbs_pr_debug(1, "Reset wpa_ie_len=%d IE=%#x\n",
- adapter->wpa_ie_len, adapter->wpa_ie[0]);
- adapter->secinfo.WPAenabled = 0;
- adapter->secinfo.WPA2enabled = 0;
- }
-
- // enable/disable RSN in firmware if WPA is enabled/disabled
- // depending on variable adapter->secinfo.WPAenabled is set or not
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_enable_rsn,
- cmd_act_set, cmd_option_waitforrsp,
- 0, NULL);
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Set Auto prescan
- * @param priv A pointer to wlan_private structure
- * @param wrq A pointer to iwreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_subcmd_setprescan_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
- int data;
- wlan_adapter *adapter = priv->adapter;
- int *val;
-
- data = SUBCMD_DATA(wrq);
- lbs_pr_debug(1, "WLAN_SUBCMD_SET_PRESCAN %d\n", data);
- adapter->prescan = data;
-
- val = (int *)wrq->u.name;
- *val = data;
- return 0;
-}
-
-static int wlan_set_multiple_dtim_ioctl(wlan_private * priv, struct ifreq *req)
-{
- struct iwreq *wrq = (struct iwreq *)req;
- u32 mdtim;
- int idata;
- int ret = -EINVAL;
-
- ENTER();
-
- idata = SUBCMD_DATA(wrq);
- mdtim = (u32) idata;
- if (((mdtim >= MRVDRV_MIN_MULTIPLE_DTIM)
- && (mdtim <= MRVDRV_MAX_MULTIPLE_DTIM))
- || (mdtim == MRVDRV_IGNORE_MULTIPLE_DTIM)) {
- priv->adapter->multipledtim = mdtim;
- ret = 0;
- }
- if (ret)
- lbs_pr_debug(1, "Invalid parameter, multipledtim not changed.\n");
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Set authentication mode
- * @param priv A pointer to wlan_private structure
- * @param req A pointer to ifreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_setauthalg_ioctl(wlan_private * priv, struct ifreq *req)
-{
- int alg;
- struct iwreq *wrq = (struct iwreq *)req;
- wlan_adapter *adapter = priv->adapter;
-
- if (wrq->u.data.flags == 0) {
- //from iwpriv subcmd
- alg = SUBCMD_DATA(wrq);
- } else {
- //from wpa_supplicant subcmd
- if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(alg))) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
- }
-
- lbs_pr_debug(1, "auth alg is %#x\n", alg);
-
- switch (alg) {
- case AUTH_ALG_SHARED_KEY:
- adapter->secinfo.authmode = wlan802_11authmodeshared;
- break;
- case AUTH_ALG_NETWORK_EAP:
- adapter->secinfo.authmode =
- wlan802_11authmodenetworkEAP;
- break;
- case AUTH_ALG_OPEN_SYSTEM:
- default:
- adapter->secinfo.authmode = wlan802_11authmodeopen;
- break;
- }
- return 0;
-}
-
-/**
- * @brief Set 802.1x authentication mode
- * @param priv A pointer to wlan_private structure
- * @param req A pointer to ifreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_set8021xauthalg_ioctl(wlan_private * priv, struct ifreq *req)
-{
- int alg;
- struct iwreq *wrq = (struct iwreq *)req;
-
- if (wrq->u.data.flags == 0) {
- //from iwpriv subcmd
- alg = SUBCMD_DATA(wrq);
- } else {
- //from wpa_supplicant subcmd
- if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(int))) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
- }
- lbs_pr_debug(1, "802.1x auth alg is %#x\n", alg);
- priv->adapter->secinfo.auth1xalg = alg;
- return 0;
-}
-
-static int wlan_setencryptionmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
- int mode;
- struct iwreq *wrq = (struct iwreq *)req;
-
- ENTER();
-
- if (wrq->u.data.flags == 0) {
- //from iwpriv subcmd
- mode = SUBCMD_DATA(wrq);
- } else {
- //from wpa_supplicant subcmd
- if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
- }
- lbs_pr_debug(1, "encryption mode is %#x\n", mode);
- priv->adapter->secinfo.Encryptionmode = mode;
-
- LEAVE();
- return 0;
-}
-
-static void adjust_mtu(wlan_private * priv)
-{
- int mtu_increment = 0;
-
- if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
- mtu_increment += sizeof(struct ieee80211_hdr_4addr);
-
- if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP)
- mtu_increment += max(sizeof(struct tx_radiotap_hdr),
- sizeof(struct rx_radiotap_hdr));
- priv->wlan_dev.netdev->mtu = ETH_FRAME_LEN
- - sizeof(struct ethhdr)
- + mtu_increment;
-}
-
-/**
- * @brief Set Link-Layer Layer mode
- * @param priv A pointer to wlan_private structure
- * @param req A pointer to ifreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_set_linkmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
- int mode;
-
- mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
-
- switch (mode) {
- case WLAN_LINKMODE_802_3:
- priv->adapter->linkmode = mode;
- break;
- case WLAN_LINKMODE_802_11:
- priv->adapter->linkmode = mode;
- break;
- default:
- lbs_pr_info("usb8388-5: invalid link-layer mode (%#x)\n",
- mode);
- return -EINVAL;
- break;
- }
- lbs_pr_debug(1, "usb8388-5: link-layer mode is %#x\n", mode);
-
- adjust_mtu(priv);
-
- return 0;
-}
-
-/**
- * @brief Set Radio header mode
- * @param priv A pointer to wlan_private structure
- * @param req A pointer to ifreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_set_radiomode_ioctl(wlan_private * priv, struct ifreq *req)
-{
- int mode;
-
- mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
-
- switch (mode) {
- case WLAN_RADIOMODE_NONE:
- priv->adapter->radiomode = mode;
- break;
- case WLAN_RADIOMODE_RADIOTAP:
- priv->adapter->radiomode = mode;
- break;
- default:
- lbs_pr_debug(1, "usb8388-5: invalid radio header mode (%#x)\n",
- mode);
- return -EINVAL;
- }
- lbs_pr_debug(1, "usb8388-5: radio-header mode is %#x\n", mode);
-
- adjust_mtu(priv);
- return 0;
-}
-
-/**
- * @brief Set Debug header mode
- * @param priv A pointer to wlan_private structure
- * @param req A pointer to ifreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_set_debugmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
- priv->adapter->debugmode = (int)((struct ifreq *)
- ((u8 *) req + 4))->ifr_data;
- return 0;
-}
-
-static int wlan_subcmd_getrxantenna_ioctl(wlan_private * priv,
- struct ifreq *req)
-{
- int len;
- char buf[8];
- struct iwreq *wrq = (struct iwreq *)req;
-
- lbs_pr_debug(1, "WLAN_SUBCMD_GETRXANTENNA\n");
- len = getrxantenna(priv, buf);
-
- wrq->u.data.length = len;
- if (wrq->u.data.pointer) {
- if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
- lbs_pr_debug(1, "CopyToUser failed\n");
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-static int wlan_subcmd_gettxantenna_ioctl(wlan_private * priv,
- struct ifreq *req)
-{
- int len;
- char buf[8];
- struct iwreq *wrq = (struct iwreq *)req;
-
- lbs_pr_debug(1, "WLAN_SUBCMD_GETTXANTENNA\n");
- len = gettxantenna(priv, buf);
-
- wrq->u.data.length = len;
- if (wrq->u.data.pointer) {
- if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
- lbs_pr_debug(1, "CopyToUser failed\n");
- return -EFAULT;
- }
- }
- return 0;
-}
-
-/**
- * @brief Get the MAC TSF value from the firmware
- *
- * @param priv A pointer to wlan_private structure
- * @param wrq A pointer to iwreq structure containing buffer
- * space to store a TSF value retrieved from the firmware
- *
- * @return 0 if successful; IOCTL error code otherwise
- */
-static int wlan_get_tsf_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
- u64 tsfval;
- int ret;
-
- ret = libertas_prepare_and_send_command(priv,
- cmd_get_tsf,
- 0, cmd_option_waitforrsp, 0, &tsfval);
-
- lbs_pr_debug(1, "IOCTL: Get TSF = 0x%016llx\n", tsfval);
-
- if (ret != 0) {
- lbs_pr_debug(1, "IOCTL: Get TSF; command exec failed\n");
- ret = -EFAULT;
- } else {
- if (copy_to_user(wrq->u.data.pointer,
- &tsfval,
- min_t(size_t, wrq->u.data.length,
- sizeof(tsfval))) != 0) {
-
- lbs_pr_debug(1, "IOCTL: Get TSF; Copy to user failed\n");
- ret = -EFAULT;
- } else {
- ret = 0;
- }
- }
- return ret;
-}
-
-/**
- * @brief Get/Set adapt rate
- * @param priv A pointer to wlan_private structure
- * @param wrq A pointer to iwreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_adapt_rateset(wlan_private * priv, struct iwreq *wrq)
-{
- int ret;
- wlan_adapter *adapter = priv->adapter;
- int data[2];
-
- memset(data, 0, sizeof(data));
- if (!wrq->u.data.length) {
- lbs_pr_debug(1, "Get ADAPT RATE SET\n");
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_rate_adapt_rateset,
- cmd_act_get,
- cmd_option_waitforrsp, 0, NULL);
- data[0] = adapter->enablehwauto;
- data[1] = adapter->ratebitmap;
- if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
-#define GET_TWO_INT 2
- wrq->u.data.length = GET_TWO_INT;
- } else {
- lbs_pr_debug(1, "Set ADAPT RATE SET\n");
- if (wrq->u.data.length > 2)
- return -EINVAL;
- if (copy_from_user
- (data, wrq->u.data.pointer,
- sizeof(int) * wrq->u.data.length)) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
-
- adapter->enablehwauto = data[0];
- adapter->ratebitmap = data[1];
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_rate_adapt_rateset,
- cmd_act_set,
- cmd_option_waitforrsp, 0, NULL);
- }
- return ret;
-}
-
-/**
- * @brief Get/Set inactivity timeout
- * @param priv A pointer to wlan_private structure
- * @param wrq A pointer to iwreq structure
- * @return 0 --success, otherwise fail
- */
-static int wlan_inactivity_timeout(wlan_private * priv, struct iwreq *wrq)
-{
- int ret;
- int data = 0;
- u16 timeout = 0;
-
- ENTER();
- if (wrq->u.data.length > 1)
- return -ENOTSUPP;
-
- if (wrq->u.data.length == 0) {
- /* Get */
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_inactivity_timeout,
- cmd_act_get,
- cmd_option_waitforrsp, 0,
- &timeout);
- data = timeout;
- if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
- } else {
- /* Set */
- if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
-
- timeout = data;
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_inactivity_timeout,
- cmd_act_set,
- cmd_option_waitforrsp, 0,
- &timeout);
- }
-
- wrq->u.data.length = 1;
-
- LEAVE();
- return ret;
-}
-
-static int wlan_do_getlog_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
- int ret;
- char buf[GETLOG_BUFSIZE - 1];
- wlan_adapter *adapter = priv->adapter;
-
- lbs_pr_debug(1, " GET STATS\n");
-
- ret = libertas_prepare_and_send_command(priv, cmd_802_11_get_log,
- 0, cmd_option_waitforrsp, 0, NULL);
-
- if (ret) {
- return ret;
- }
-
- if (wrq->u.data.pointer) {
- sprintf(buf, "\n mcasttxframe %u failed %u retry %u "
- "multiretry %u framedup %u "
- "rtssuccess %u rtsfailure %u ackfailure %u\n"
- "rxfrag %u mcastrxframe %u fcserror %u "
- "txframe %u wepundecryptable %u ",
- adapter->logmsg.mcasttxframe,
- adapter->logmsg.failed,
- adapter->logmsg.retry,
- adapter->logmsg.multiretry,
- adapter->logmsg.framedup,
- adapter->logmsg.rtssuccess,
- adapter->logmsg.rtsfailure,
- adapter->logmsg.ackfailure,
- adapter->logmsg.rxfrag,
- adapter->logmsg.mcastrxframe,
- adapter->logmsg.fcserror,
- adapter->logmsg.txframe,
- adapter->logmsg.wepundecryptable);
- wrq->u.data.length = strlen(buf) + 1;
- if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-static int wlan_scan_type_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
- u8 buf[12];
- u8 *option[] = { "active", "passive", "get", };
- int i, max_options = (sizeof(option) / sizeof(option[0]));
- int ret = 0;
- wlan_adapter *adapter = priv->adapter;
-
- if (priv->adapter->enable11d) {
- lbs_pr_debug(1, "11D: Cannot set scantype when 11D enabled\n");
- return -EFAULT;
- }
-
- memset(buf, 0, sizeof(buf));
-
- if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
- wrq->u.data.length)))
- return -EFAULT;
-
- lbs_pr_debug(1, "Scan type Option = %s\n", buf);
-
- buf[sizeof(buf) - 1] = '\0';
-
- for (i = 0; i < max_options; i++) {
- if (!strcmp(buf, option[i]))
- break;
- }
-
- switch (i) {
- case 0:
- adapter->scantype = cmd_scan_type_active;
- break;
- case 1:
- adapter->scantype = cmd_scan_type_passive;
- break;
- case 2:
- wrq->u.data.length = strlen(option[adapter->scantype]) + 1;
-
- if (copy_to_user(wrq->u.data.pointer,
- option[adapter->scantype],
- wrq->u.data.length)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- ret = -EFAULT;
- }
-
- break;
- default:
- lbs_pr_debug(1, "Invalid Scan type Ioctl Option\n");
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int wlan_scan_mode_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
- wlan_adapter *adapter = priv->adapter;
- u8 buf[12];
- u8 *option[] = { "bss", "ibss", "any", "get" };
- int i, max_options = (sizeof(option) / sizeof(option[0]));
- int ret = 0;
-
- ENTER();
-
- memset(buf, 0, sizeof(buf));
-
- if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
- wrq->u.data.length))) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
-
- lbs_pr_debug(1, "Scan mode Option = %s\n", buf);
-
- buf[sizeof(buf) - 1] = '\0';
-
- for (i = 0; i < max_options; i++) {
- if (!strcmp(buf, option[i]))
- break;
- }
-
- switch (i) {
-
- case 0:
- adapter->scanmode = cmd_bss_type_bss;
- break;
- case 1:
- adapter->scanmode = cmd_bss_type_ibss;
- break;
- case 2:
- adapter->scanmode = cmd_bss_type_any;
- break;
- case 3:
-
- wrq->u.data.length = strlen(option[adapter->scanmode - 1]) + 1;
-
- lbs_pr_debug(1, "Get Scan mode Option = %s\n",
- option[adapter->scanmode - 1]);
-
- lbs_pr_debug(1, "Scan mode length %d\n", wrq->u.data.length);
-
- if (copy_to_user(wrq->u.data.pointer,
- option[adapter->scanmode - 1],
- wrq->u.data.length)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- ret = -EFAULT;
- }
- lbs_pr_debug(1, "GET Scan type Option after copy = %s\n",
- (char *)wrq->u.data.pointer);
-
- break;
-
- default:
- lbs_pr_debug(1, "Invalid Scan mode Ioctl Option\n");
- ret = -EINVAL;
- break;
- }
-
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Get/Set Adhoc G Rate
- *
- * @param priv A pointer to wlan_private structure
- * @param wrq A pointer to user data
- * @return 0--success, otherwise fail
- */
-static int wlan_do_set_grate_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
- wlan_adapter *adapter = priv->adapter;
- int data, data1;
- int *val;
-
- ENTER();
-
- data1 = SUBCMD_DATA(wrq);
- switch (data1) {
- case 0:
- adapter->adhoc_grate_enabled = 0;
- break;
- case 1:
- adapter->adhoc_grate_enabled = 1;
- break;
- case 2:
- break;
- default:
- return -EINVAL;
- }
- data = adapter->adhoc_grate_enabled;
- val = (int *)wrq->u.name;
- *val = data;
- LEAVE();
- return 0;
-}
-
static inline int hex2int(char c)
{
if (c >= '0' && c <= '9')
@@ -1761,6 +680,7 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
*/
static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
{
+ struct iwreq *wrq = (struct iwreq *)req;
static struct cmd_ds_fwt_access fwt_access;
int ret;
@@ -1776,7 +696,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
(void *)&fwt_access);
if (ret == 0)
- req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
+ wrq->u.param.value = le32_to_cpu(fwt_access.references);
else
return -EFAULT;
@@ -1792,6 +712,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
*/
static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
{
+ struct iwreq *wrq = (struct iwreq *)req;
static struct cmd_ds_fwt_access fwt_access;
int ret;
@@ -1807,7 +728,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
(void *)&fwt_access);
if (ret == 0)
- req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
+ wrq->u.param.value = le32_to_cpu(fwt_access.references);
else
return -EFAULT;
@@ -1823,6 +744,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
*/
static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
{
+ struct iwreq *wrq = (struct iwreq *)req;
struct cmd_ds_mesh_access mesh_access;
int ret;
@@ -1835,9 +757,8 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
cmd_option_waitforrsp, 0,
(void *)&mesh_access);
- if (ret == 0) {
- req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0]));
- }
+ if (ret == 0)
+ wrq->u.param.value = le32_to_cpu(mesh_access.data[0]);
else
return -EFAULT;
@@ -1898,36 +819,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
switch (cmd) {
- case WLANSCAN_TYPE:
- lbs_pr_debug(1, "Scan type Ioctl\n");
- ret = wlan_scan_type_ioctl(priv, wrq);
- break;
-
case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */
switch (wrq->u.data.flags) {
- case WLANDEAUTH:
- lbs_pr_debug(1, "Deauth\n");
- libertas_send_deauth(priv);
- break;
-
- case WLANADHOCSTOP:
- lbs_pr_debug(1, "Adhoc stop\n");
- ret = libertas_do_adhocstop_ioctl(priv);
- break;
-
- case WLANRADIOON:
- wlan_radio_ioctl(priv, 1);
- break;
-
- case WLANRADIOOFF:
- wlan_radio_ioctl(priv, 0);
- break;
- case WLANWLANIDLEON:
- libertas_idle_on(priv);
- break;
- case WLANWLANIDLEOFF:
- libertas_idle_off(priv);
- break;
case WLAN_SUBCMD_BT_RESET: /* bt_reset */
wlan_bt_reset_ioctl(priv);
break;
@@ -1937,162 +830,19 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
} /* End of switch */
break;
- case WLANSETWPAIE:
- ret = wlan_setwpaie_ioctl(priv, req);
- break;
- case WLAN_SETINT_GETINT:
- /* The first 4 bytes of req->ifr_data is sub-ioctl number
- * after 4 bytes sits the payload.
- */
- subcmd = (int)req->ifr_data; //from iwpriv subcmd
- switch (subcmd) {
- case WLANNF:
- ret = wlan_get_nf(priv, wrq);
- break;
- case WLANRSSI:
- ret = wlan_get_rssi(priv, wrq);
- break;
- case WLANENABLE11D:
- ret = libertas_cmd_enable_11d(priv, wrq);
- break;
- case WLANADHOCGRATE:
- ret = wlan_do_set_grate_ioctl(priv, wrq);
- break;
- case WLAN_SUBCMD_SET_PRESCAN:
- ret = wlan_subcmd_setprescan_ioctl(priv, wrq);
- break;
- }
- break;
-
- case WLAN_SETONEINT_GETONEINT:
- switch (wrq->u.data.flags) {
- case WLAN_BEACON_INTERVAL:
- ret = wlan_beacon_interval(priv, wrq);
- break;
-
- case WLAN_LISTENINTRVL:
- if (!wrq->u.data.length) {
- int data;
- lbs_pr_debug(1, "Get locallisteninterval value\n");
-#define GET_ONE_INT 1
- data = adapter->locallisteninterval;
- if (copy_to_user(wrq->u.data.pointer,
- &data, sizeof(int))) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
-
- wrq->u.data.length = GET_ONE_INT;
- } else {
- int data;
- if (copy_from_user
- (&data, wrq->u.data.pointer, sizeof(int))) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
-
- lbs_pr_debug(1, "Set locallisteninterval = %d\n",
- data);
-#define MAX_U16_VAL 65535
- if (data > MAX_U16_VAL) {
- lbs_pr_debug(1, "Exceeds U16 value\n");
- return -EINVAL;
- }
- adapter->locallisteninterval = data;
- }
- break;
- case WLAN_TXCONTROL:
- ret = wlan_txcontrol(priv, wrq); //adds for txcontrol ioctl
- break;
-
- case WLAN_NULLPKTINTERVAL:
- ret = wlan_null_pkt_interval(priv, wrq);
- break;
-
- default:
- ret = -EOPNOTSUPP;
- break;
- }
- break;
-
case WLAN_SETONEINT_GETNONE:
/* The first 4 bytes of req->ifr_data is sub-ioctl number
* after 4 bytes sits the payload.
*/
- subcmd = wrq->u.data.flags; //from wpa_supplicant subcmd
-
+ subcmd = wrq->u.data.flags;
if (!subcmd)
- subcmd = (int)req->ifr_data; //from iwpriv subcmd
+ subcmd = (int)wrq->u.param.value;
switch (subcmd) {
- case WLAN_SUBCMD_SETRXANTENNA: /* SETRXANTENNA */
- idata = SUBCMD_DATA(wrq);
- ret = setrxantenna(priv, idata);
- break;
- case WLAN_SUBCMD_SETTXANTENNA: /* SETTXANTENNA */
- idata = SUBCMD_DATA(wrq);
- ret = settxantenna(priv, idata);
- break;
- case WLAN_SET_ATIM_WINDOW:
- adapter->atimwindow = SUBCMD_DATA(wrq);
- adapter->atimwindow = min_t(__u16, adapter->atimwindow, 50);
- break;
- case WLANSETBCNAVG:
- adapter->bcn_avg_factor = SUBCMD_DATA(wrq);
- if (adapter->bcn_avg_factor == 0)
- adapter->bcn_avg_factor =
- DEFAULT_BCN_AVG_FACTOR;
- if (adapter->bcn_avg_factor > DEFAULT_BCN_AVG_FACTOR)
- adapter->bcn_avg_factor =
- DEFAULT_BCN_AVG_FACTOR;
- break;
- case WLANSETDATAAVG:
- adapter->data_avg_factor = SUBCMD_DATA(wrq);
- if (adapter->data_avg_factor == 0)
- adapter->data_avg_factor =
- DEFAULT_DATA_AVG_FACTOR;
- if (adapter->data_avg_factor > DEFAULT_DATA_AVG_FACTOR)
- adapter->data_avg_factor =
- DEFAULT_DATA_AVG_FACTOR;
- break;
case WLANSETREGION:
idata = SUBCMD_DATA(wrq);
ret = wlan_set_region(priv, (u16) idata);
break;
-
- case WLAN_SET_LISTEN_INTERVAL:
- idata = SUBCMD_DATA(wrq);
- adapter->listeninterval = (u16) idata;
- break;
-
- case WLAN_SET_MULTIPLE_DTIM:
- ret = wlan_set_multiple_dtim_ioctl(priv, req);
- break;
-
- case WLANSETAUTHALG:
- ret = wlan_setauthalg_ioctl(priv, req);
- break;
-
- case WLANSET8021XAUTHALG:
- ret = wlan_set8021xauthalg_ioctl(priv, req);
- break;
-
- case WLANSETENCRYPTIONMODE:
- ret = wlan_setencryptionmode_ioctl(priv, req);
- break;
-
- case WLAN_SET_LINKMODE:
- ret = wlan_set_linkmode_ioctl(priv, req);
- break;
-
- case WLAN_SET_RADIOMODE:
- ret = wlan_set_radiomode_ioctl(priv, req);
- break;
-
- case WLAN_SET_DEBUGMODE:
- ret = wlan_set_debugmode_ioctl(priv, req);
- break;
-
case WLAN_SUBCMD_MESH_SET_TTL:
idata = SUBCMD_DATA(wrq);
ret = wlan_mesh_set_ttl_ioctl(priv, idata);
@@ -2105,38 +855,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
break;
- case WLAN_SETNONE_GETTWELVE_CHAR: /* Get Antenna settings */
- /*
- * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
- * in flags of iwreq structure, otherwise it will be in
- * mode member of iwreq structure.
- */
- switch ((int)wrq->u.data.flags) {
- case WLAN_SUBCMD_GETRXANTENNA: /* Get Rx Antenna */
- ret = wlan_subcmd_getrxantenna_ioctl(priv, req);
- break;
-
- case WLAN_SUBCMD_GETTXANTENNA: /* Get Tx Antenna */
- ret = wlan_subcmd_gettxantenna_ioctl(priv, req);
- break;
-
- case WLAN_GET_TSF:
- ret = wlan_get_tsf_ioctl(priv, wrq);
- break;
- }
- break;
-
case WLAN_SET128CHAR_GET128CHAR:
switch ((int)wrq->u.data.flags) {
-
- case WLANSCAN_MODE:
- lbs_pr_debug(1, "Scan mode Ioctl\n");
- ret = wlan_scan_mode_ioctl(priv, wrq);
- break;
-
- case WLAN_GET_ADHOC_STATUS:
- ret = wlan_get_adhoc_status_ioctl(priv, wrq);
- break;
case WLAN_SUBCMD_BT_ADD:
ret = wlan_bt_add_ioctl(priv, req);
break;
@@ -2168,41 +888,11 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
break;
case WLAN_SETNONE_GETONEINT:
- switch ((int)req->ifr_data) {
- case WLANGETBCNAVG:
- pdata = (int *)wrq->u.name;
- *pdata = (int)adapter->bcn_avg_factor;
- break;
-
+ switch (wrq->u.param.value) {
case WLANGETREGION:
pdata = (int *)wrq->u.name;
*pdata = (int)adapter->regioncode;
break;
-
- case WLAN_GET_LISTEN_INTERVAL:
- pdata = (int *)wrq->u.name;
- *pdata = (int)adapter->listeninterval;
- break;
-
- case WLAN_GET_LINKMODE:
- req->ifr_data = (char *)((u32) adapter->linkmode);
- break;
-
- case WLAN_GET_RADIOMODE:
- req->ifr_data = (char *)((u32) adapter->radiomode);
- break;
-
- case WLAN_GET_DEBUGMODE:
- req->ifr_data = (char *)((u32) adapter->debugmode);
- break;
-
- case WLAN_GET_MULTIPLE_DTIM:
- pdata = (int *)wrq->u.name;
- *pdata = (int)adapter->multipledtim;
- break;
- case WLAN_GET_TX_RATE:
- ret = wlan_get_txrate_ioctl(priv, req);
- break;
case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */
ret = wlan_fwt_cleanup_ioctl(priv, req);
break;
@@ -2222,196 +912,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
break;
- case WLANGETLOG:
- ret = wlan_do_getlog_ioctl(priv, wrq);
- break;
-
case WLAN_SET_GET_SIXTEEN_INT:
switch ((int)wrq->u.data.flags) {
- case WLAN_TPCCFG:
- {
- int data[5];
- struct cmd_ds_802_11_tpc_cfg cfg;
- memset(&cfg, 0, sizeof(cfg));
- if ((wrq->u.data.length > 1)
- && (wrq->u.data.length != 5))
- return -1;
-
- if (wrq->u.data.length == 0) {
- cfg.action =
- cpu_to_le16
- (cmd_act_get);
- } else {
- if (copy_from_user
- (data, wrq->u.data.pointer,
- sizeof(int) * 5)) {
- lbs_pr_debug(1,
- "Copy from user failed\n");
- return -EFAULT;
- }
-
- cfg.action =
- cpu_to_le16
- (cmd_act_set);
- cfg.enable = data[0];
- cfg.usesnr = data[1];
- cfg.P0 = data[2];
- cfg.P1 = data[3];
- cfg.P2 = data[4];
- }
-
- ret =
- libertas_prepare_and_send_command(priv,
- cmd_802_11_tpc_cfg,
- 0,
- cmd_option_waitforrsp,
- 0, (void *)&cfg);
-
- data[0] = cfg.enable;
- data[1] = cfg.usesnr;
- data[2] = cfg.P0;
- data[3] = cfg.P1;
- data[4] = cfg.P2;
- if (copy_to_user
- (wrq->u.data.pointer, data,
- sizeof(int) * 5)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
-
- wrq->u.data.length = 5;
- }
- break;
-
- case WLAN_POWERCFG:
- {
- int data[4];
- struct cmd_ds_802_11_pwr_cfg cfg;
- memset(&cfg, 0, sizeof(cfg));
- if ((wrq->u.data.length > 1)
- && (wrq->u.data.length != 4))
- return -1;
- if (wrq->u.data.length == 0) {
- cfg.action =
- cpu_to_le16
- (cmd_act_get);
- } else {
- if (copy_from_user
- (data, wrq->u.data.pointer,
- sizeof(int) * 4)) {
- lbs_pr_debug(1,
- "Copy from user failed\n");
- return -EFAULT;
- }
-
- cfg.action =
- cpu_to_le16
- (cmd_act_set);
- cfg.enable = data[0];
- cfg.PA_P0 = data[1];
- cfg.PA_P1 = data[2];
- cfg.PA_P2 = data[3];
- }
- ret =
- libertas_prepare_and_send_command(priv,
- cmd_802_11_pwr_cfg,
- 0,
- cmd_option_waitforrsp,
- 0, (void *)&cfg);
- data[0] = cfg.enable;
- data[1] = cfg.PA_P0;
- data[2] = cfg.PA_P1;
- data[3] = cfg.PA_P2;
- if (copy_to_user
- (wrq->u.data.pointer, data,
- sizeof(int) * 4)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
-
- wrq->u.data.length = 4;
- }
- break;
- case WLAN_AUTO_FREQ_SET:
- {
- int data[3];
- struct cmd_ds_802_11_afc afc;
- memset(&afc, 0, sizeof(afc));
- if (wrq->u.data.length != 3)
- return -1;
- if (copy_from_user
- (data, wrq->u.data.pointer,
- sizeof(int) * 3)) {
- lbs_pr_debug(1, "Copy from user failed\n");
- return -EFAULT;
- }
- afc.afc_auto = data[0];
-
- if (afc.afc_auto != 0) {
- afc.threshold = data[1];
- afc.period = data[2];
- } else {
- afc.timing_offset = data[1];
- afc.carrier_offset = data[2];
- }
- ret =
- libertas_prepare_and_send_command(priv,
- cmd_802_11_set_afc,
- 0,
- cmd_option_waitforrsp,
- 0, (void *)&afc);
- }
- break;
- case WLAN_AUTO_FREQ_GET:
- {
- int data[3];
- struct cmd_ds_802_11_afc afc;
- memset(&afc, 0, sizeof(afc));
- ret =
- libertas_prepare_and_send_command(priv,
- cmd_802_11_get_afc,
- 0,
- cmd_option_waitforrsp,
- 0, (void *)&afc);
- data[0] = afc.afc_auto;
- data[1] = afc.timing_offset;
- data[2] = afc.carrier_offset;
- if (copy_to_user
- (wrq->u.data.pointer, data,
- sizeof(int) * 3)) {
- lbs_pr_debug(1, "Copy to user failed\n");
- return -EFAULT;
- }
-
- wrq->u.data.length = 3;
- }
- break;
- case WLAN_SCANPROBES:
- {
- int data;
- if (wrq->u.data.length > 0) {
- if (copy_from_user
- (&data, wrq->u.data.pointer,
- sizeof(int))) {
- lbs_pr_debug(1,
- "Copy from user failed\n");
- return -EFAULT;
- }
-
- adapter->scanprobes = data;
- } else {
- data = adapter->scanprobes;
- if (copy_to_user
- (wrq->u.data.pointer, &data,
- sizeof(int))) {
- lbs_pr_debug(1,
- "Copy to user failed\n");
- return -EFAULT;
- }
- }
- wrq->u.data.length = 1;
- }
- break;
case WLAN_LED_GPIO_CTRL:
{
int i;
@@ -2475,17 +977,6 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
wrq->u.data.length = gpio->header.len;
}
break;
- case WLAN_ADAPT_RATESET:
- ret = wlan_adapt_rateset(priv, wrq);
- break;
- case WLAN_INACTIVITY_TIMEOUT:
- ret = wlan_inactivity_timeout(priv, wrq);
- break;
- case WLANSNR:
- ret = wlan_get_snr(priv, wrq);
- break;
- case WLAN_GET_RXINFO:
- ret = wlan_get_rxinfo(priv, wrq);
}
break;
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index 11682cbe752..d4926b83e14 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -15,6 +15,8 @@
#include "join.h"
#include "dev.h"
+#define AD_HOC_CAP_PRIVACY_ON 1
+
/**
* @brief This function finds out the common rates between rate1 and rate2.
*
@@ -85,7 +87,7 @@ int libertas_send_deauth(wlan_private * priv)
wlan_adapter *adapter = priv->adapter;
int ret = 0;
- if (adapter->inframode == wlan802_11infrastructure &&
+ if (adapter->mode == IW_MODE_INFRA &&
adapter->connect_status == libertas_connected)
ret = libertas_send_deauthentication(priv);
else
@@ -94,20 +96,6 @@ int libertas_send_deauth(wlan_private * priv)
return ret;
}
-int libertas_do_adhocstop_ioctl(wlan_private * priv)
-{
- wlan_adapter *adapter = priv->adapter;
- int ret = 0;
-
- if (adapter->inframode == wlan802_11ibss &&
- adapter->connect_status == libertas_connected)
- ret = libertas_stop_adhoc_network(priv);
- else
- ret = -ENOTSUPP;
-
- return ret;
-}
-
/**
* @brief Associate to a specific BSS discovered in a scan
*
@@ -207,8 +195,7 @@ int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbs
/* check if the requested SSID is already joined */
if (adapter->curbssparams.ssid.ssidlength
&& !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid)
- && (adapter->curbssparams.bssdescriptor.inframode ==
- wlan802_11ibss)) {
+ && (adapter->mode == IW_MODE_ADHOC)) {
lbs_pr_debug(1,
"ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
@@ -261,130 +248,6 @@ int libertas_send_deauthentication(wlan_private * priv)
}
/**
- * @brief Set Idle Off
- *
- * @param priv A pointer to wlan_private structure
- * @return 0 --success, otherwise fail
- */
-int libertas_idle_off(wlan_private * priv)
-{
- wlan_adapter *adapter = priv->adapter;
- int ret = 0;
- const u8 zeromac[] = { 0, 0, 0, 0, 0, 0 };
- int i;
-
- ENTER();
-
- if (adapter->connect_status == libertas_disconnected) {
- if (adapter->inframode == wlan802_11infrastructure) {
- if (memcmp(adapter->previousbssid, zeromac,
- sizeof(zeromac)) != 0) {
-
- lbs_pr_debug(1, "Previous SSID = %s\n",
- adapter->previousssid.ssid);
- lbs_pr_debug(1, "Previous BSSID = "
- "%02x:%02x:%02x:%02x:%02x:%02x:\n",
- adapter->previousbssid[0],
- adapter->previousbssid[1],
- adapter->previousbssid[2],
- adapter->previousbssid[3],
- adapter->previousbssid[4],
- adapter->previousbssid[5]);
-
- i = libertas_find_SSID_in_list(adapter,
- &adapter->previousssid,
- adapter->previousbssid,
- adapter->inframode);
-
- if (i < 0) {
- libertas_send_specific_BSSID_scan(priv,
- adapter->
- previousbssid,
- 1);
- i = libertas_find_SSID_in_list(adapter,
- &adapter->
- previousssid,
- adapter->
- previousbssid,
- adapter->
- inframode);
- }
-
- if (i < 0) {
- /* If the BSSID could not be found, try just the SSID */
- i = libertas_find_SSID_in_list(adapter,
- &adapter->
- previousssid, NULL,
- adapter->
- inframode);
- }
-
- if (i < 0) {
- libertas_send_specific_SSID_scan(priv,
- &adapter->
- previousssid,
- 1);
- i = libertas_find_SSID_in_list(adapter,
- &adapter->
- previousssid, NULL,
- adapter->
- inframode);
- }
-
- if (i >= 0) {
- ret =
- wlan_associate(priv,
- &adapter->
- scantable[i]);
- }
- }
- } else if (adapter->inframode == wlan802_11ibss) {
- ret = libertas_prepare_and_send_command(priv,
- cmd_802_11_ad_hoc_start,
- 0,
- cmd_option_waitforrsp,
- 0, &adapter->previousssid);
- }
- }
- /* else it is connected */
-
- lbs_pr_debug(1, "\nwlanidle is off");
- LEAVE();
- return ret;
-}
-
-/**
- * @brief Set Idle On
- *
- * @param priv A pointer to wlan_private structure
- * @return 0 --success, otherwise fail
- */
-int libertas_idle_on(wlan_private * priv)
-{
- wlan_adapter *adapter = priv->adapter;
- int ret = 0;
-
- if (adapter->connect_status == libertas_connected) {
- if (adapter->inframode == wlan802_11infrastructure) {
- lbs_pr_debug(1, "Previous SSID = %s\n",
- adapter->previousssid.ssid);
- memmove(&adapter->previousssid,
- &adapter->curbssparams.ssid,
- sizeof(struct WLAN_802_11_SSID));
- libertas_send_deauth(priv);
-
- } else if (adapter->inframode == wlan802_11ibss) {
- ret = libertas_stop_adhoc_network(priv);
- }
-
- }
-
- lbs_pr_debug(1, "\nwlanidle is on");
-
- return ret;
-}
-
-/**
* @brief This function prepares command of authenticate.
*
* @param priv A pointer to wlan_private structure
@@ -398,22 +261,39 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
void *pdata_buf)
{
wlan_adapter *adapter = priv->adapter;
- struct cmd_ds_802_11_authenticate *pauthenticate =
- &cmd->params.auth;
+ struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
+ int ret = -1;
u8 *bssid = pdata_buf;
cmd->command = cpu_to_le16(cmd_802_11_authenticate);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
- + S_DS_GEN);
+ cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
+ + S_DS_GEN);
+
+ /* translate auth mode to 802.11 defined wire value */
+ switch (adapter->secinfo.auth_mode) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ pauthenticate->authtype = 0x00;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ pauthenticate->authtype = 0x01;
+ break;
+ case IW_AUTH_ALG_LEAP:
+ pauthenticate->authtype = 0x80;
+ break;
+ default:
+ lbs_pr_debug(1, "AUTH_CMD: invalid auth alg 0x%X\n",
+ adapter->secinfo.auth_mode);
+ goto out;
+ }
- pauthenticate->authtype = adapter->secinfo.authmode;
memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n",
bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
+ ret = 0;
- return 0;
+out:
+ return ret;
}
int libertas_cmd_80211_deauthenticate(wlan_private * priv,
@@ -550,7 +430,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len);
/* set IBSS field */
- if (pbssdesc->inframode == wlan802_11infrastructure) {
+ if (pbssdesc->mode == IW_MODE_INFRA) {
#define CAPINFO_ESS_MODE 1
passo->capinfo.ess = CAPINFO_ESS_MODE;
}
@@ -624,7 +504,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
/* set the BSS type */
adhs->bsstype = cmd_bss_type_ibss;
- pbssdesc->inframode = wlan802_11ibss;
+ pbssdesc->mode = IW_MODE_ADHOC;
adhs->beaconperiod = adapter->beaconperiod;
/* set Physical param set */
@@ -666,15 +546,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
/* set up privacy in adapter->scantable[i] */
- if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
-
-#define AD_HOC_CAP_PRIVACY_ON 1
- lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus set, privacy to WEP\n");
+ if (adapter->secinfo.wep_enabled) {
+ lbs_pr_debug(1, "ADHOC_S_CMD: WEP enabled, setting privacy on\n");
pbssdesc->privacy = wlan802_11privfilter8021xWEP;
adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
} else {
- lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus NOT set, Setting "
- "privacy to ACCEPT ALL\n");
+ lbs_pr_debug(1, "ADHOC_S_CMD: WEP disabled, setting privacy off\n");
pbssdesc->privacy = wlan802_11privfilteracceptall;
}
@@ -786,9 +663,6 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
padhocjoin->bssdescriptor.BSSID[5],
padhocjoin->bssdescriptor.SSID);
- lbs_pr_debug(1, "ADHOC_J_CMD: Data Rate = %x\n",
- (u32) padhocjoin->bssdescriptor.datarates);
-
/* failtimeout */
padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
@@ -832,7 +706,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
cpu_to_le16(pbssdesc->atimwindow);
- if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
+ if (adapter->secinfo.wep_enabled) {
padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
}
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h
index 8efa2455af9..115f5a8ba34 100644
--- a/drivers/net/wireless/libertas/join.h
+++ b/drivers/net/wireless/libertas/join.h
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
/**
* Interface for the wlan infrastructure and adhoc join routines
*
@@ -40,10 +37,6 @@ extern int libertas_ret_80211_disassociate(wlan_private * priv,
extern int libertas_ret_80211_associate(wlan_private * priv,
struct cmd_ds_command *resp);
-extern int libertas_idle_on(wlan_private * priv);
-extern int libertas_idle_off(wlan_private * priv);
-
-extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
extern int libertas_reassociation_thread(void *data);
struct WLAN_802_11_SSID;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index dcbf102a057..b9b25ce6591 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -21,6 +21,13 @@
#include "debugfs.h"
#include "assoc.h"
+#define DRIVER_RELEASE_VERSION "320.p0"
+const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
+#ifdef DEBUG
+ "-dbg"
+#endif
+ "";
+
#ifdef ENABLE_PM
static struct pm_dev *wlan_pm_dev = NULL;
#endif
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 7e3f78f092d..d17924f764e 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -210,7 +210,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
goto done;
}
- lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
+ lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
@@ -364,7 +364,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
priv->stats.rx_errors++;
}
- lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
+ lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
/* create the exported radio header */
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index e1870623895..3c0b1a2a172 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
/**
* Functions implementing wlan scan IOCTL and firmware command APIs
*
@@ -87,118 +84,95 @@
*
* @return Index in scantable, or error code if negative
*/
-static int is_network_compatible(wlan_adapter * adapter, int index, int mode)
+static int is_network_compatible(wlan_adapter * adapter, int index, u8 mode)
{
ENTER();
- if (adapter->scantable[index].inframode == mode) {
- if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+ if (adapter->scantable[index].mode == mode) {
+ if ( !adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
- && adapter->scantable[index].wpa_supplicant.wpa_ie[0] !=
- WPA_IE
- && adapter->scantable[index].wpa2_supplicant.wpa_ie[0] !=
- WPA2_IE && adapter->secinfo.Encryptionmode == CIPHER_NONE
+ && adapter->scantable[index].wpa_ie[0] != WPA_IE
+ && adapter->scantable[index].rsn_ie[0] != WPA2_IE
&& !adapter->scantable[index].privacy) {
/* no security */
LEAVE();
return index;
- } else if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled
+ } else if ( adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
&& adapter->scantable[index].privacy) {
/* static WEP enabled */
LEAVE();
return index;
- } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+ } else if ( !adapter->secinfo.wep_enabled
&& adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
- && (adapter->scantable[index].wpa_supplicant.
- wpa_ie[0]
- == WPA_IE)
+ && (adapter->scantable[index].wpa_ie[0] == WPA_IE)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& adapter->scantable[index].privacy */
) {
/* WPA enabled */
- lbs_pr_debug(1,
+ lbs_pr_debug(1,
"is_network_compatible() WPA: index=%d wpa_ie=%#x "
- "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
+ "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
"privacy=%#x\n", index,
- adapter->scantable[index].wpa_supplicant.
- wpa_ie[0],
- adapter->scantable[index].wpa2_supplicant.
- wpa_ie[0],
- (adapter->secinfo.WEPstatus ==
- wlan802_11WEPenabled) ? "e" : "d",
- (adapter->secinfo.WPAenabled) ? "e" : "d",
- (adapter->secinfo.WPA2enabled) ? "e" : "d",
- adapter->secinfo.Encryptionmode,
+ adapter->scantable[index].wpa_ie[0],
+ adapter->scantable[index].rsn_ie[0],
+ adapter->secinfo.wep_enabled ? "e" : "d",
+ adapter->secinfo.WPAenabled ? "e" : "d",
+ adapter->secinfo.WPA2enabled ? "e" : "d",
adapter->scantable[index].privacy);
LEAVE();
return index;
- } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+ } else if ( !adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& adapter->secinfo.WPA2enabled
- && (adapter->scantable[index].wpa2_supplicant.
- wpa_ie[0]
- == WPA2_IE)
+ && (adapter->scantable[index].rsn_ie[0] == WPA2_IE)
/* privacy bit may NOT be set in some APs like LinkSys WRT54G
&& adapter->scantable[index].privacy */
) {
/* WPA2 enabled */
- lbs_pr_debug(1,
+ lbs_pr_debug(1,
"is_network_compatible() WPA2: index=%d wpa_ie=%#x "
- "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
+ "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
"privacy=%#x\n", index,
- adapter->scantable[index].wpa_supplicant.
- wpa_ie[0],
- adapter->scantable[index].wpa2_supplicant.
- wpa_ie[0],
- (adapter->secinfo.WEPstatus ==
- wlan802_11WEPenabled) ? "e" : "d",
- (adapter->secinfo.WPAenabled) ? "e" : "d",
- (adapter->secinfo.WPA2enabled) ? "e" : "d",
- adapter->secinfo.Encryptionmode,
+ adapter->scantable[index].wpa_ie[0],
+ adapter->scantable[index].rsn_ie[0],
+ adapter->secinfo.wep_enabled ? "e" : "d",
+ adapter->secinfo.WPAenabled ? "e" : "d",
+ adapter->secinfo.WPA2enabled ? "e" : "d",
adapter->scantable[index].privacy);
LEAVE();
return index;
- } else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+ } else if ( !adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled
- && (adapter->scantable[index].wpa_supplicant.
- wpa_ie[0]
- != WPA_IE)
- && (adapter->scantable[index].wpa2_supplicant.
- wpa_ie[0]
- != WPA2_IE)
- && adapter->secinfo.Encryptionmode != CIPHER_NONE
+ && (adapter->scantable[index].wpa_ie[0] != WPA_IE)
+ && (adapter->scantable[index].rsn_ie[0] != WPA2_IE)
&& adapter->scantable[index].privacy) {
/* dynamic WEP enabled */
- lbs_pr_debug(1,
+ lbs_pr_debug(1,
"is_network_compatible() dynamic WEP: index=%d "
- "wpa_ie=%#x wpa2_ie=%#x Encmode=%#x privacy=%#x\n",
+ "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
index,
- adapter->scantable[index].wpa_supplicant.
- wpa_ie[0],
- adapter->scantable[index].wpa2_supplicant.
- wpa_ie[0], adapter->secinfo.Encryptionmode,
+ adapter->scantable[index].wpa_ie[0],
+ adapter->scantable[index].rsn_ie[0],
adapter->scantable[index].privacy);
LEAVE();
return index;
}
/* security doesn't match */
- lbs_pr_debug(1,
+ lbs_pr_debug(1,
"is_network_compatible() FAILED: index=%d wpa_ie=%#x "
- "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x privacy=%#x\n",
+ "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
index,
- adapter->scantable[index].wpa_supplicant.wpa_ie[0],
- adapter->scantable[index].wpa2_supplicant.wpa_ie[0],
- (adapter->secinfo.WEPstatus ==
- wlan802_11WEPenabled) ? "e" : "d",
- (adapter->secinfo.WPAenabled) ? "e" : "d",
- (adapter->secinfo.WPA2enabled) ? "e" : "d",
- adapter->secinfo.Encryptionmode,
+ adapter->scantable[index].wpa_ie[0],
+ adapter->scantable[index].rsn_ie[0],
+ adapter->secinfo.wep_enabled ? "e" : "d",
+ adapter->secinfo.WPAenabled ? "e" : "d",
+ adapter->secinfo.WPA2enabled ? "e" : "d",
adapter->scantable[index].privacy);
LEAVE();
return -ECONNREFUSED;
@@ -924,8 +898,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
u8 founddatarateie;
int bytesleftforcurrentbeacon;
- struct WPA_SUPPLICANT *pwpa_supplicant;
- struct WPA_SUPPLICANT *pwpa2_supplicant;
struct IE_WPA *pIe;
const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
@@ -962,9 +934,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
bytesleftforcurrentbeacon = beaconsize;
- pwpa_supplicant = &pBSSEntry->wpa_supplicant;
- pwpa2_supplicant = &pBSSEntry->wpa2_supplicant;
-
memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN);
lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n",
pBSSEntry->macaddress[0], pBSSEntry->macaddress[1],
@@ -1027,9 +996,9 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
}
if (pcap->ibss == 1) {
- pBSSEntry->inframode = wlan802_11ibss;
+ pBSSEntry->mode = IW_MODE_ADHOC;
} else {
- pBSSEntry->inframode = wlan802_11infrastructure;
+ pBSSEntry->mode = IW_MODE_INFRA;
}
/* process variable IE */
@@ -1116,7 +1085,7 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
sizeof(pcountryinfo->countrycode)
|| pcountryinfo->len > 254) {
lbs_pr_debug(1, "InterpretIE: 11D- Err "
- "CountryInfo len =%d min=%d max=254\n",
+ "CountryInfo len =%d min=%zd max=254\n",
pcountryinfo->len,
sizeof(pcountryinfo->countrycode));
LEAVE();
@@ -1160,27 +1129,27 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
#define IE_ID_LEN_FIELDS_BYTES 2
pIe = (struct IE_WPA *)pcurrentptr;
- if (!memcmp(pIe->oui, oui01, sizeof(oui01))) {
- pwpa_supplicant->wpa_ie_len
- = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
- sizeof(pwpa_supplicant->wpa_ie));
- memcpy(pwpa_supplicant->wpa_ie,
- pcurrentptr,
- pwpa_supplicant->wpa_ie_len);
- lbs_dbg_hex("InterpretIE: Resp WPA_IE",
- pwpa_supplicant->wpa_ie, elemlen);
- }
+ if (memcmp(pIe->oui, oui01, sizeof(oui01)))
+ break;
+
+ pBSSEntry->wpa_ie_len = min_t(size_t,
+ elemlen + IE_ID_LEN_FIELDS_BYTES,
+ sizeof(pBSSEntry->wpa_ie));
+ memcpy(pBSSEntry->wpa_ie, pcurrentptr,
+ pBSSEntry->wpa_ie_len);
+ lbs_dbg_hex("InterpretIE: Resp WPA_IE",
+ pBSSEntry->wpa_ie, elemlen);
break;
case WPA2_IE:
pIe = (struct IE_WPA *)pcurrentptr;
- pwpa2_supplicant->wpa_ie_len
- = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
- sizeof(pwpa2_supplicant->wpa_ie));
- memcpy(pwpa2_supplicant->wpa_ie,
- pcurrentptr, pwpa2_supplicant->wpa_ie_len);
+ pBSSEntry->rsn_ie_len = min_t(size_t,
+ elemlen + IE_ID_LEN_FIELDS_BYTES,
+ sizeof(pBSSEntry->rsn_ie));
+ memcpy(pBSSEntry->rsn_ie, pcurrentptr,
+ pBSSEntry->rsn_ie_len);
lbs_dbg_hex("InterpretIE: Resp WPA2_IE",
- pwpa2_supplicant->wpa_ie, elemlen);
+ pBSSEntry->rsn_ie, elemlen);
break;
case TIM:
break;
@@ -1227,7 +1196,7 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s
*
* @return index in BSSID list, or error return code (< 0)
*/
-int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
+int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode)
{
int ret = -ENETUNREACH;
int i;
@@ -1247,8 +1216,8 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
for (i = 0; ret < 0 && i < adapter->numinscantable; i++) {
if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) {
switch (mode) {
- case wlan802_11infrastructure:
- case wlan802_11ibss:
+ case IW_MODE_INFRA:
+ case IW_MODE_ADHOC:
ret = is_network_compatible(adapter, i, mode);
break;
default:
@@ -1272,7 +1241,7 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
* @return index in BSSID list
*/
int libertas_find_SSID_in_list(wlan_adapter * adapter,
- struct WLAN_802_11_SSID *ssid, u8 * bssid, int mode)
+ struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode)
{
int net = -ENETUNREACH;
u8 bestrssi = 0;
@@ -1287,8 +1256,8 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
!memcmp(adapter->scantable[i].
macaddress, bssid, ETH_ALEN))) {
switch (mode) {
- case wlan802_11infrastructure:
- case wlan802_11ibss:
+ case IW_MODE_INFRA:
+ case IW_MODE_ADHOC:
j = is_network_compatible(adapter, i, mode);
if (j >= 0) {
@@ -1311,7 +1280,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
}
}
break;
- case wlan802_11autounknown:
+ case IW_MODE_AUTO:
default:
if (SCAN_RSSI(adapter->scantable[i].rssi)
> bestrssi) {
@@ -1338,8 +1307,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
*
* @return index in BSSID list
*/
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode)
+int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode)
{
int bestnet = -ENETUNREACH;
u8 bestrssi = 0;
@@ -1351,8 +1319,8 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
for (i = 0; i < adapter->numinscantable; i++) {
switch (mode) {
- case wlan802_11infrastructure:
- case wlan802_11ibss:
+ case IW_MODE_INFRA:
+ case IW_MODE_ADHOC:
if (is_network_compatible(adapter, i, mode) >= 0) {
if (SCAN_RSSI(adapter->scantable[i].rssi) >
bestrssi) {
@@ -1363,7 +1331,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
}
}
break;
- case wlan802_11autounknown:
+ case IW_MODE_AUTO:
default:
if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) {
bestrssi =
@@ -1388,8 +1356,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
*/
int libertas_find_best_network_SSID(wlan_private * priv,
struct WLAN_802_11_SSID *pSSID,
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode)
+ u8 preferred_mode, u8 *out_mode)
{
wlan_adapter *adapter = priv->adapter;
int ret = 0;
@@ -1414,7 +1381,7 @@ int libertas_find_best_network_SSID(wlan_private * priv,
preqbssid = &adapter->scantable[i];
memcpy(pSSID, &preqbssid->ssid,
sizeof(struct WLAN_802_11_SSID));
- *out_mode = preqbssid->inframode;
+ *out_mode = preqbssid->mode;
if (!pSSID->ssidlength) {
ret = -1;
@@ -1584,7 +1551,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
for (i = 0; i < adapter->numinscantable; i++) {
if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) {
lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p "
- "MAX_SCAN_CELL_SIZE=%d\n",
+ "MAX_SCAN_CELL_SIZE=%zd\n",
i, current_ev, end_buf, MAX_SCAN_CELL_SIZE);
break;
}
@@ -1632,7 +1599,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
//Add mode
iwe.cmd = SIOCGIWMODE;
- iwe.u.mode = adapter->scantable[i].inframode + 1;
+ iwe.u.mode = adapter->scantable[i].mode;
iwe.len = IW_EV_UINT_LEN;
current_ev =
iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
@@ -1666,7 +1633,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
iwe.u.qual.noise =
CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
}
- if ((adapter->inframode == wlan802_11ibss) &&
+ if ((adapter->mode == IW_MODE_ADHOC) &&
!libertas_SSID_cmp(&adapter->curbssparams.ssid,
&adapter->scantable[i].ssid)
&& adapter->adhoccreate) {
@@ -1731,7 +1698,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
end_buf, &iwe, iwe.len);
}
- if ((adapter->scantable[i].inframode == wlan802_11ibss)
+ if ((adapter->scantable[i].mode == IW_MODE_ADHOC)
&& !libertas_SSID_cmp(&adapter->curbssparams.ssid,
&adapter->scantable[i].ssid)
&& adapter->adhoccreate) {
@@ -1745,30 +1712,24 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
/* Add new value to event */
current_val = current_ev + IW_EV_LCP_LEN;
- if (adapter->scantable[i].wpa2_supplicant.wpa_ie[0] == WPA2_IE) {
+ if (adapter->scantable[i].rsn_ie[0] == WPA2_IE) {
memset(&iwe, 0, sizeof(iwe));
memset(buf, 0, sizeof(buf));
- memcpy(buf, adapter->scantable[i].
- wpa2_supplicant.wpa_ie,
- adapter->scantable[i].wpa2_supplicant.
- wpa_ie_len);
+ memcpy(buf, adapter->scantable[i].rsn_ie,
+ adapter->scantable[i].rsn_ie_len);
iwe.cmd = IWEVGENIE;
- iwe.u.data.length = adapter->scantable[i].
- wpa2_supplicant.wpa_ie_len;
+ iwe.u.data.length = adapter->scantable[i].rsn_ie_len;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
}
- if (adapter->scantable[i].wpa_supplicant.wpa_ie[0] == WPA_IE) {
+ if (adapter->scantable[i].wpa_ie[0] == WPA_IE) {
memset(&iwe, 0, sizeof(iwe));
memset(buf, 0, sizeof(buf));
- memcpy(buf, adapter->scantable[i].
- wpa_supplicant.wpa_ie,
- adapter->scantable[i].wpa_supplicant.
- wpa_ie_len);
+ memcpy(buf, adapter->scantable[i].wpa_ie,
+ adapter->scantable[i].wpa_ie_len);
iwe.cmd = IWEVGENIE;
- iwe.u.data.length = adapter->scantable[i].
- wpa_supplicant.wpa_ie_len;
+ iwe.u.data.length = adapter->scantable[i].wpa_ie_len;
iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, buf);
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
index d93aa7fa44f..405f4f0fe57 100644
--- a/drivers/net/wireless/libertas/scan.h
+++ b/drivers/net/wireless/libertas/scan.h
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
/**
* Interface for the wlan network scan routines
*
@@ -10,6 +7,7 @@
#ifndef _WLAN_SCAN_H
#define _WLAN_SCAN_H
+#include <net/ieee80211.h>
#include "hostcmd.h"
/**
@@ -155,7 +153,7 @@ struct bss_descriptor {
u32 atimwindow;
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
+ u8 mode;
u8 libertas_supported_rates[WLAN_SUPPORTED_RATES];
int extra_ie;
@@ -170,22 +168,22 @@ struct bss_descriptor {
struct ieeetypes_countryinfofullset countryinfo;
- struct WPA_SUPPLICANT wpa_supplicant;
- struct WPA_SUPPLICANT wpa2_supplicant;
-
+ u8 wpa_ie[MAX_WPA_IE_LEN];
+ size_t wpa_ie_len;
+ u8 rsn_ie[MAX_WPA_IE_LEN];
+ size_t rsn_ie_len;
};
extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1,
struct WLAN_802_11_SSID *ssid2);
extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid,
- u8 * bssid, int mode);
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter, enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode);
-extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode);
+ u8 * bssid, u8 mode);
+int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode);
+extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode);
int libertas_find_best_network_SSID(wlan_private * priv,
struct WLAN_802_11_SSID *pSSID,
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode);
+ u8 preferred_mode, u8 *out_mode);
extern int libertas_send_specific_SSID_scan(wlan_private * priv,
struct WLAN_802_11_SSID *prequestedssid,
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 82d06223043..d4b13478c9a 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -78,7 +78,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
min_t(unsigned int, skb->len, 100));
if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
- lbs_pr_debug(1, "Tx error: Bad skb length %d : %d\n",
+ lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n",
skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
ret = -1;
goto done;
diff --git a/drivers/net/wireless/libertas/version.h b/drivers/net/wireless/libertas/version.h
index e86f65ae79b..8b137891791 100644
--- a/drivers/net/wireless/libertas/version.h
+++ b/drivers/net/wireless/libertas/version.h
@@ -1,8 +1 @@
-#define DRIVER_RELEASE_VERSION "320.p0"
-const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
-#ifdef DEBUG
- "-dbg"
-#endif
- "";
-
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 4a52336bc0f..69f52b6e59c 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -17,7 +17,6 @@
#include "defs.h"
#include "dev.h"
#include "join.h"
-#include "version.h"
#include "wext.h"
#include "assoc.h"
@@ -233,7 +232,7 @@ static int changeadhocchannel(wlan_private * priv, int channel)
// find out the BSSID that matches the current SSID
i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
- wlan802_11ibss);
+ IW_MODE_ADHOC);
if (i >= 0) {
lbs_pr_debug(1, "SSID found at %d in List,"
@@ -316,13 +315,11 @@ static int get_active_data_rates(wlan_adapter * adapter,
ENTER();
if (adapter->connect_status != libertas_connected) {
- if (adapter->inframode == wlan802_11infrastructure) {
- //Infra. mode
+ if (adapter->mode == IW_MODE_INFRA) {
lbs_pr_debug(1, "Infra\n");
k = copyrates(rates, k, libertas_supported_rates,
sizeof(libertas_supported_rates));
} else {
- //ad-hoc mode
lbs_pr_debug(1, "Adhoc G\n");
k = copyrates(rates, k, libertas_adhoc_rates_g,
sizeof(libertas_adhoc_rates_g));
@@ -586,20 +583,7 @@ static int wlan_get_mode(struct net_device *dev,
ENTER();
- switch (adapter->inframode) {
- case wlan802_11ibss:
- *uwrq = IW_MODE_ADHOC;
- break;
-
- case wlan802_11infrastructure:
- *uwrq = IW_MODE_INFRA;
- break;
-
- default:
- case wlan802_11autounknown:
- *uwrq = IW_MODE_AUTO;
- break;
- }
+ *uwrq = adapter->mode;
LEAVE();
return 0;
@@ -1002,149 +986,18 @@ static const struct iw_priv_args wlan_private_args[] = {
/*
* { cmd, set_args, get_args, name }
*/
- {
- WLANSCAN_TYPE,
- IW_PRIV_TYPE_CHAR | 8,
- IW_PRIV_TYPE_CHAR | 8,
- "scantype"},
-
- {
- WLAN_SETINT_GETINT,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- ""},
- {
- WLANNF,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getNF"},
- {
- WLANRSSI,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getRSSI"},
- {
- WLANENABLE11D,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "enable11d"},
- {
- WLANADHOCGRATE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "adhocgrate"},
-
- {
- WLAN_SUBCMD_SET_PRESCAN,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "prescan"},
- {
- WLAN_SETONEINT_GETONEINT,
- IW_PRIV_TYPE_INT | 1,
- IW_PRIV_TYPE_INT | 1,
- ""},
- {
- WLAN_BEACON_INTERVAL,
- IW_PRIV_TYPE_INT | 1,
- IW_PRIV_TYPE_INT | 1,
- "bcninterval"},
- {
- WLAN_LISTENINTRVL,
- IW_PRIV_TYPE_INT | 1,
- IW_PRIV_TYPE_INT | 1,
- "lolisteninter"},
- {
- WLAN_TXCONTROL,
- IW_PRIV_TYPE_INT | 1,
- IW_PRIV_TYPE_INT | 1,
- "txcontrol"},
- {
- WLAN_NULLPKTINTERVAL,
- IW_PRIV_TYPE_INT | 1,
- IW_PRIV_TYPE_INT | 1,
- "psnullinterval"},
/* Using iwpriv sub-command feature */
{
WLAN_SETONEINT_GETNONE, /* IOCTL: 24 */
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
IW_PRIV_TYPE_NONE,
""},
-
- {
- WLAN_SUBCMD_SETRXANTENNA,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "setrxant"},
- {
- WLAN_SUBCMD_SETTXANTENNA,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "settxant"},
- {
- WLANSETAUTHALG,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "authalgs",
- },
- {
- WLANSET8021XAUTHALG,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "8021xauthalgs",
- },
- {
- WLANSETENCRYPTIONMODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "encryptionmode",
- },
{
WLANSETREGION,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
IW_PRIV_TYPE_NONE,
"setregioncode"},
{
- WLAN_SET_LISTEN_INTERVAL,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "setlisteninter"},
- {
- WLAN_SET_MULTIPLE_DTIM,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "setmultipledtim"},
- {
- WLAN_SET_ATIM_WINDOW,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "atimwindow"},
- {
- WLANSETBCNAVG,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "setbcnavg"},
- {
- WLANSETDATAAVG,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "setdataavg"},
- {
- WLAN_SET_LINKMODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "linkmode"},
- {
- WLAN_SET_RADIOMODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "radiomode"},
- {
- WLAN_SET_DEBUGMODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- IW_PRIV_TYPE_NONE,
- "debugmode"},
- {
WLAN_SUBCMD_MESH_SET_TTL,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
IW_PRIV_TYPE_NONE,
@@ -1160,41 +1013,6 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"getregioncode"},
{
- WLAN_GET_LISTEN_INTERVAL,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getlisteninter"},
- {
- WLAN_GET_MULTIPLE_DTIM,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getmultipledtim"},
- {
- WLAN_GET_TX_RATE,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "gettxrate"},
- {
- WLANGETBCNAVG,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getbcnavg"},
- {
- WLAN_GET_LINKMODE,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_linkmode"},
- {
- WLAN_GET_RADIOMODE,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_radiomode"},
- {
- WLAN_GET_DEBUGMODE,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_debugmode"},
- {
WLAN_SUBCMD_FWT_CLEANUP,
IW_PRIV_TYPE_NONE,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -1210,61 +1028,11 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"mesh_get_ttl"},
{
- WLAN_SETNONE_GETTWELVE_CHAR,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_CHAR | 12,
- ""},
- {
- WLAN_SUBCMD_GETRXANTENNA,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_CHAR | 12,
- "getrxant"},
- {
- WLAN_SUBCMD_GETTXANTENNA,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_CHAR | 12,
- "gettxant"},
- {
- WLAN_GET_TSF,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_CHAR | 12,
- "gettsf"},
- {
WLAN_SETNONE_GETNONE,
IW_PRIV_TYPE_NONE,
IW_PRIV_TYPE_NONE,
""},
{
- WLANDEAUTH,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_NONE,
- "deauth"},
- {
- WLANADHOCSTOP,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_NONE,
- "adhocstop"},
- {
- WLANRADIOON,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_NONE,
- "radioon"},
- {
- WLANRADIOOFF,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_NONE,
- "radiooff"},
- {
- WLANWLANIDLEON,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_NONE,
- "wlanidle-on"},
- {
- WLANWLANIDLEOFF,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_NONE,
- "wlanidle-off"},
- {
WLAN_SUBCMD_FWT_RESET,
IW_PRIV_TYPE_NONE,
IW_PRIV_TYPE_NONE,
@@ -1327,90 +1095,15 @@ static const struct iw_priv_args wlan_private_args[] = {
IW_PRIV_TYPE_CHAR | 128,
"fwt_list_route"},
{
- WLANSCAN_MODE,
- IW_PRIV_TYPE_CHAR | 128,
- IW_PRIV_TYPE_CHAR | 128,
- "scanmode"},
- {
- WLAN_GET_ADHOC_STATUS,
- IW_PRIV_TYPE_CHAR | 128,
- IW_PRIV_TYPE_CHAR | 128,
- "getadhocstatus"},
- {
- WLAN_SETNONE_GETWORDCHAR,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_CHAR | 128,
- ""},
- {
- WLANSETWPAIE,
- IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 24,
- IW_PRIV_TYPE_NONE,
- "setwpaie"},
- {
- WLANGETLOG,
- IW_PRIV_TYPE_NONE,
- IW_PRIV_TYPE_CHAR | GETLOG_BUFSIZE,
- "getlog"},
- {
WLAN_SET_GET_SIXTEEN_INT,
IW_PRIV_TYPE_INT | 16,
IW_PRIV_TYPE_INT | 16,
""},
{
- WLAN_TPCCFG,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "tpccfg"},
- {
- WLAN_POWERCFG,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "powercfg"},
- {
- WLAN_AUTO_FREQ_SET,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "setafc"},
- {
- WLAN_AUTO_FREQ_GET,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "getafc"},
- {
- WLAN_SCANPROBES,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "scanprobes"},
- {
WLAN_LED_GPIO_CTRL,
IW_PRIV_TYPE_INT | 16,
IW_PRIV_TYPE_INT | 16,
"ledgpio"},
- {
- WLAN_ADAPT_RATESET,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "rateadapt"},
- {
- WLAN_INACTIVITY_TIMEOUT,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "inactivityto"},
- {
- WLANSNR,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "getSNR"},
- {
- WLAN_GET_RATE,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "getrate"},
- {
- WLAN_GET_RXINFO,
- IW_PRIV_TYPE_INT | 16,
- IW_PRIV_TYPE_INT | 16,
- "getrxinfo"},
};
static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
@@ -1434,7 +1127,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
ENTER();
- priv->wstats.status = adapter->inframode;
+ priv->wstats.status = adapter->mode;
/* If we're not associated, all quality values are meaningless */
if (adapter->connect_status != libertas_connected)
@@ -1568,13 +1261,12 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
if (!cfp) {
rc = -EINVAL;
} else {
- if (adapter->inframode == wlan802_11ibss) {
+ if (adapter->mode == IW_MODE_ADHOC) {
rc = changeadhocchannel(priv, channel);
/* If station is WEP enabled, send the
* command to set WEP in firmware
*/
- if (adapter->secinfo.WEPstatus ==
- wlan802_11WEPenabled) {
+ if (adapter->secinfo.wep_enabled) {
lbs_pr_debug(1, "set_freq: WEP enabled\n");
ret = libertas_prepare_and_send_command(priv,
cmd_802_11_set_wep,
@@ -1716,49 +1408,31 @@ static int wlan_set_mode(struct net_device *dev,
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
struct assoc_request * assoc_req;
- enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
ENTER();
- switch (*uwrq) {
- case IW_MODE_ADHOC:
- lbs_pr_debug(1, "Wanted mode is ad-hoc: current datarate=%#x\n",
- adapter->datarate);
- new_mode = wlan802_11ibss;
- adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
- break;
-
- case IW_MODE_INFRA:
- lbs_pr_debug(1, "Wanted mode is Infrastructure\n");
- new_mode = wlan802_11infrastructure;
- break;
-
- case IW_MODE_AUTO:
- lbs_pr_debug(1, "Wanted mode is Auto\n");
- new_mode = wlan802_11autounknown;
- break;
-
- default:
- lbs_pr_debug(1, "Wanted mode is Unknown: 0x%x\n", *uwrq);
- return -EINVAL;
+ if ( (*uwrq != IW_MODE_ADHOC)
+ && (*uwrq != IW_MODE_INFRA)
+ && (*uwrq != IW_MODE_AUTO)) {
+ lbs_pr_debug(1, "Invalid mode: 0x%x\n", *uwrq);
+ ret = -EINVAL;
+ goto out;
}
mutex_lock(&adapter->lock);
assoc_req = wlan_get_association_request(adapter);
if (!assoc_req) {
ret = -ENOMEM;
+ wlan_cancel_association_work(priv);
} else {
- assoc_req->mode = new_mode;
- }
-
- if (ret == 0) {
+ assoc_req->mode = *uwrq;
set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
wlan_postpone_association_work(priv);
- } else {
- wlan_cancel_association_work(priv);
+ lbs_pr_debug(1, "Switching to mode: 0x%x\n", *uwrq);
}
mutex_unlock(&adapter->lock);
+out:
LEAVE();
return ret;
}
@@ -1789,13 +1463,13 @@ static int wlan_get_encode(struct net_device *dev,
dwrq->flags = 0;
/* Authentication method */
- switch (adapter->secinfo.authmode) {
- case wlan802_11authmodeopen:
+ switch (adapter->secinfo.auth_mode) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
dwrq->flags = IW_ENCODE_OPEN;
break;
- case wlan802_11authmodeshared:
- case wlan802_11authmodenetworkEAP:
+ case IW_AUTH_ALG_SHARED_KEY:
+ case IW_AUTH_ALG_LEAP:
dwrq->flags = IW_ENCODE_RESTRICTED;
break;
default:
@@ -1803,8 +1477,9 @@ static int wlan_get_encode(struct net_device *dev,
break;
}
- if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
- || adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
+ if ( adapter->secinfo.wep_enabled
+ || adapter->secinfo.WPAenabled
+ || adapter->secinfo.WPA2enabled) {
dwrq->flags &= ~IW_ENCODE_DISABLED;
} else {
dwrq->flags |= IW_ENCODE_DISABLED;
@@ -1818,8 +1493,7 @@ static int wlan_get_encode(struct net_device *dev,
if (index < 0)
index = adapter->wep_tx_keyidx;
- if ((adapter->wep_keys[index].len) &&
- (adapter->secinfo.WEPstatus == wlan802_11WEPenabled)) {
+ if ((adapter->wep_keys[index].len) && adapter->secinfo.wep_enabled) {
memcpy(extra, adapter->wep_keys[index].key,
adapter->wep_keys[index].len);
dwrq->length = adapter->wep_keys[index].len;
@@ -1903,7 +1577,7 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req,
assoc_req->wep_tx_keyidx = index;
}
- assoc_req->secinfo.WEPstatus = wlan802_11WEPenabled;
+ assoc_req->secinfo.wep_enabled = 1;
LEAVE();
return 0;
@@ -1932,10 +1606,10 @@ static void disable_wep(struct assoc_request *assoc_req)
int i;
/* Set Open System auth mode */
- assoc_req->secinfo.authmode = wlan802_11authmodeopen;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
/* Clear WEP keys and mark WEP as disabled */
- assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
+ assoc_req->secinfo.wep_enabled = 0;
for (i = 0; i < 4; i++)
assoc_req->wep_keys[i].len = 0;
@@ -1987,8 +1661,7 @@ static int wlan_set_encode(struct net_device *dev,
/* If WEP isn't enabled, or if there is no key data but a valid
* index, set the TX key.
*/
- if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
- || (dwrq->length == 0 && !is_default))
+ if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default))
set_tx_key = 1;
ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
@@ -2001,9 +1674,9 @@ static int wlan_set_encode(struct net_device *dev,
set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
if (dwrq->flags & IW_ENCODE_RESTRICTED) {
- assoc_req->secinfo.authmode = wlan802_11authmodeshared;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
} else if (dwrq->flags & IW_ENCODE_OPEN) {
- assoc_req->secinfo.authmode = wlan802_11authmodeopen;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
}
out:
@@ -2056,30 +1729,31 @@ static int wlan_get_encodeext(struct net_device *dev,
if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
ext->alg != IW_ENCODE_ALG_WEP) {
- if (index != 0 || adapter->inframode != wlan802_11infrastructure)
+ if (index != 0 || adapter->mode != IW_MODE_INFRA)
goto out;
}
dwrq->flags = index + 1;
memset(ext, 0, sizeof(*ext));
- if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled)
- && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) {
+ if ( !adapter->secinfo.wep_enabled
+ && !adapter->secinfo.WPAenabled
+ && !adapter->secinfo.WPA2enabled) {
ext->alg = IW_ENCODE_ALG_NONE;
ext->key_len = 0;
dwrq->flags |= IW_ENCODE_DISABLED;
} else {
u8 *key = NULL;
- if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
+ if ( adapter->secinfo.wep_enabled
&& !adapter->secinfo.WPAenabled
&& !adapter->secinfo.WPA2enabled) {
ext->alg = IW_ENCODE_ALG_WEP;
ext->key_len = adapter->wep_keys[index].len;
key = &adapter->wep_keys[index].key[0];
- } else if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled) &&
- (adapter->secinfo.WPAenabled ||
- adapter->secinfo.WPA2enabled)) {
+ } else if ( !adapter->secinfo.wep_enabled
+ && (adapter->secinfo.WPAenabled ||
+ adapter->secinfo.WPA2enabled)) {
/* WPA */
ext->alg = IW_ENCODE_ALG_TKIP;
ext->key_len = 0;
@@ -2149,7 +1823,7 @@ static int wlan_set_encodeext(struct net_device *dev,
/* If WEP isn't enabled, or if there is no key data but a valid
* index, or if the set-TX-key flag was passed, set the TX key.
*/
- if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
+ if ( !assoc_req->secinfo.wep_enabled
|| (dwrq->length == 0 && !is_default)
|| (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY))
set_tx_key = 1;
@@ -2161,11 +1835,9 @@ static int wlan_set_encodeext(struct net_device *dev,
goto out;
if (dwrq->flags & IW_ENCODE_RESTRICTED) {
- assoc_req->secinfo.authmode =
- wlan802_11authmodeshared;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
} else if (dwrq->flags & IW_ENCODE_OPEN) {
- assoc_req->secinfo.authmode =
- wlan802_11authmodeopen;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
}
/* Mark the various WEP bits as modified */
@@ -2350,15 +2022,13 @@ static int wlan_set_auth(struct net_device *dev,
}
if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
assoc_req->secinfo.WPAenabled = 1;
- assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
- assoc_req->secinfo.authmode =
- wlan802_11authmodeopen;
+ assoc_req->secinfo.wep_enabled = 0;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
}
if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) {
assoc_req->secinfo.WPA2enabled = 1;
- assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
- assoc_req->secinfo.authmode =
- wlan802_11authmodeopen;
+ assoc_req->secinfo.wep_enabled = 0;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
}
updated = 1;
break;
@@ -2376,14 +2046,11 @@ static int wlan_set_auth(struct net_device *dev,
case IW_AUTH_80211_AUTH_ALG:
if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
- assoc_req->secinfo.authmode =
- wlan802_11authmodeshared;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
} else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- assoc_req->secinfo.authmode =
- wlan802_11authmodeopen;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
} else if (dwrq->value & IW_AUTH_ALG_LEAP) {
- assoc_req->secinfo.authmode =
- wlan802_11authmodenetworkEAP;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_LEAP;
} else {
ret = -EINVAL;
}
@@ -2396,9 +2063,8 @@ static int wlan_set_auth(struct net_device *dev,
!assoc_req->secinfo.WPA2enabled) {
assoc_req->secinfo.WPAenabled = 1;
assoc_req->secinfo.WPA2enabled = 1;
- assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
- assoc_req->secinfo.authmode =
- wlan802_11authmodeopen;
+ assoc_req->secinfo.wep_enabled = 0;
+ assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
}
} else {
assoc_req->secinfo.WPAenabled = 0;
@@ -2455,19 +2121,7 @@ static int wlan_get_auth(struct net_device *dev,
break;
case IW_AUTH_80211_AUTH_ALG:
- switch (adapter->secinfo.authmode) {
- case wlan802_11authmodeshared:
- dwrq->value = IW_AUTH_ALG_SHARED_KEY;
- break;
- case wlan802_11authmodeopen:
- dwrq->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case wlan802_11authmodenetworkEAP:
- dwrq->value = IW_AUTH_ALG_LEAP;
- break;
- default:
- break;
- }
+ dwrq->value = adapter->secinfo.auth_mode;
break;
case IW_AUTH_WPA_ENABLED:
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
index 39f367c38d9..15cfaaf0797 100644
--- a/drivers/net/wireless/libertas/wext.h
+++ b/drivers/net/wireless/libertas/wext.h
@@ -10,88 +10,22 @@
/** PRIVATE CMD ID */
#define WLANIOCTL SIOCIWFIRSTPRIV
-#define WLANSETWPAIE (WLANIOCTL + 0)
-
-#define WLAN_SETINT_GETINT (WLANIOCTL + 7)
-#define WLANNF 1
-#define WLANRSSI 2
-#define WLANENABLE11D 5
-#define WLANADHOCGRATE 6
-#define WLAN_SUBCMD_SET_PRESCAN 11
-
#define WLAN_SETNONE_GETNONE (WLANIOCTL + 8)
-#define WLANDEAUTH 1
-#define WLANRADIOON 2
-#define WLANRADIOOFF 3
-#define WLANREMOVEADHOCAES 4
-#define WLANADHOCSTOP 5
-#define WLANCIPHERTEST 6
-#define WLANCRYPTOTEST 7
-
-#define WLANWLANIDLEON 10
-#define WLANWLANIDLEOFF 11
#define WLAN_SUBCMD_BT_RESET 13
#define WLAN_SUBCMD_FWT_RESET 14
-#define WLANGETLOG (WLANIOCTL + 9)
-#define GETLOG_BUFSIZE 300
-
-#define WLANSCAN_TYPE (WLANIOCTL + 11)
-
#define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15)
#define WLANGETREGION 1
-#define WLAN_GET_LISTEN_INTERVAL 2
-#define WLAN_GET_MULTIPLE_DTIM 3
-#define WLAN_GET_TX_RATE 4
-#define WLANGETBCNAVG 5
-#define WLAN_GET_LINKMODE 6
-#define WLAN_GET_RADIOMODE 7
-#define WLAN_GET_DEBUGMODE 8
#define WLAN_SUBCMD_FWT_CLEANUP 15
#define WLAN_SUBCMD_FWT_TIME 16
#define WLAN_SUBCMD_MESH_GET_TTL 17
-#define WLANREGCFRDWR (WLANIOCTL + 18)
-
-#define WLAN_SETNONE_GETTWELVE_CHAR (WLANIOCTL + 19)
-#define WLAN_SUBCMD_GETRXANTENNA 1
-#define WLAN_SUBCMD_GETTXANTENNA 2
-#define WLAN_GET_TSF 3
-
-#define WLAN_SETNONE_GETWORDCHAR (WLANIOCTL + 21)
-#define WLANGETADHOCAES 1
-
-#define WLAN_SETONEINT_GETONEINT (WLANIOCTL + 23)
-#define WLAN_BEACON_INTERVAL 1
-#define WLAN_LISTENINTRVL 4
-
-#define WLAN_TXCONTROL 6
-#define WLAN_NULLPKTINTERVAL 7
-
#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24)
-#define WLAN_SUBCMD_SETRXANTENNA 1
-#define WLAN_SUBCMD_SETTXANTENNA 2
-#define WLANSETAUTHALG 5
-#define WLANSET8021XAUTHALG 6
-#define WLANSETENCRYPTIONMODE 7
#define WLANSETREGION 8
-#define WLAN_SET_LISTEN_INTERVAL 9
-
-#define WLAN_SET_MULTIPLE_DTIM 10
-#define WLAN_SET_ATIM_WINDOW 11
-#define WLANSETBCNAVG 13
-#define WLANSETDATAAVG 14
-#define WLAN_SET_LINKMODE 15
-#define WLAN_SET_RADIOMODE 16
-#define WLAN_SET_DEBUGMODE 17
#define WLAN_SUBCMD_MESH_SET_TTL 18
#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25)
-#define WLANSCAN_MODE 6
-
-#define WLAN_GET_ADHOC_STATUS 9
-
#define WLAN_SUBCMD_BT_ADD 18
#define WLAN_SUBCMD_BT_DEL 19
#define WLAN_SUBCMD_BT_LIST 20
@@ -103,27 +37,8 @@
#define WLAN_SUBCMD_FWT_LIST_ROUTE 26
#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29)
-#define WLAN_TPCCFG 1
-#define WLAN_POWERCFG 2
-
-#define WLAN_AUTO_FREQ_SET 3
-#define WLAN_AUTO_FREQ_GET 4
#define WLAN_LED_GPIO_CTRL 5
-#define WLAN_SCANPROBES 6
-#define WLAN_ADAPT_RATESET 8
-#define WLAN_INACTIVITY_TIMEOUT 9
-#define WLANSNR 10
-#define WLAN_GET_RATE 11
-#define WLAN_GET_RXINFO 12
-
-#define WLANCMD52RDWR (WLANIOCTL + 30)
-#define WLANCMD53RDWR (WLANIOCTL + 31)
-#define CMD53BUFLEN 32
-#define REG_MAC 0x19
-#define REG_BBP 0x1a
-#define REG_RF 0x1b
-#define REG_EEPROM 0x59
#define WLAN_LINKMODE_802_3 0
#define WLAN_LINKMODE_802_11 2
#define WLAN_RADIOMODE_NONE 0
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 78cf0711d1f..ef07c36bccf 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -249,19 +249,19 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
if (rc == PCI_SLOT_ALREADY_UP) {
- dev_dbg(slot->pci_bus->self, "is already active\n");
+ dev_dbg(&slot->pci_bus->self->dev, "is already active\n");
return 1; /* return 1 to user */
}
if (rc == PCI_L1_ERR) {
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"L1 failure %d with message: %s",
resp.resp_sub_errno, resp.resp_l1_msg);
return -EPERM;
}
if (rc) {
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"insert failed with error %d sub-error %d\n",
rc, resp.resp_sub_errno);
return -EIO;
@@ -287,25 +287,25 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
(rc == PCI_SLOT_ALREADY_DOWN)) {
- dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
+ dev_dbg(&slot->pci_bus->self->dev, "Slot %s already inactive\n", slot->physical_path);
return 1; /* return 1 to user */
}
if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"Cannot remove last 33MHz card\n");
return -EPERM;
}
if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"L1 failure %d with message \n%s\n",
resp.resp_sub_errno, resp.resp_l1_msg);
return -EPERM;
}
if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"remove failed with error %d sub-error %d\n",
rc, resp.resp_sub_errno);
return -EIO;
@@ -317,12 +317,12 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
- dev_dbg(slot->pci_bus->self, "remove successful\n");
+ dev_dbg(&slot->pci_bus->self->dev, "remove successful\n");
return 0;
}
if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
- dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
+ dev_dbg(&slot->pci_bus->self->dev,"remove failed rc = %d\n", rc);
}
return rc;
@@ -375,7 +375,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
num_funcs = pci_scan_slot(slot->pci_bus,
PCI_DEVFN(slot->device_num + 1, 0));
if (!num_funcs) {
- dev_dbg(slot->pci_bus->self, "no device in slot\n");
+ dev_dbg(&slot->pci_bus->self->dev, "no device in slot\n");
mutex_unlock(&sn_hotplug_mutex);
return -ENODEV;
}
@@ -427,7 +427,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;
if (acpi_bus_get_device(phandle, &pdevice)) {
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"no parent device, assuming NULL\n");
pdevice = NULL;
}
@@ -479,10 +479,10 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
mutex_unlock(&sn_hotplug_mutex);
if (rc == 0)
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"insert operation successful\n");
else
- dev_dbg(slot->pci_bus->self,
+ dev_dbg(&slot->pci_bus->self->dev,
"insert operation failed rc = %d\n", rc);
return rc;
@@ -659,16 +659,16 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
if (rc)
goto register_err;
}
- dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
+ dev_dbg(&pci_bus->self->dev, "Registered bus with hotplug\n");
return rc;
register_err:
- dev_dbg(pci_bus->self, "bus failed to register with err = %d\n",
+ dev_dbg(&pci_bus->self->dev, "bus failed to register with err = %d\n",
rc);
alloc_err:
if (rc == -ENOMEM)
- dev_dbg(pci_bus->self, "Memory allocation error\n");
+ dev_dbg(&pci_bus->self->dev, "Memory allocation error\n");
/* destroy THIS element */
if (bss_hotplug_slot)
@@ -701,10 +701,10 @@ static int sn_pci_hotplug_init(void)
rc = sn_pci_bus_valid(pci_bus);
if (rc != 1) {
- dev_dbg(pci_bus->self, "not a valid hotplug bus\n");
+ dev_dbg(&pci_bus->self->dev, "not a valid hotplug bus\n");
continue;
}
- dev_dbg(pci_bus->self, "valid hotplug bus\n");
+ dev_dbg(&pci_bus->self->dev, "valid hotplug bus\n");
rc = sn_hotplug_slot_register(pci_bus);
if (!rc) {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index e6740d1a082..d9cbd586ae4 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -549,8 +549,10 @@ static int msi_free_irqs(struct pci_dev* dev)
{
struct msi_desc *entry, *tmp;
- list_for_each_entry(entry, &dev->msi_list, list)
- BUG_ON(irq_has_action(entry->irq));
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ if (entry->irq)
+ BUG_ON(irq_has_action(entry->irq));
+ }
arch_teardown_msi_irqs(dev);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 147d86f8edb..6ccc2e95930 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -875,6 +875,7 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata);
/*
* Serverworks CSB5 IDE does not fully support native mode
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 1759baad439..95ce8f49e38 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -246,7 +246,7 @@ comment "Platform RTC drivers"
config RTC_DRV_CMOS
tristate "PC-style 'CMOS'"
depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \
- || M32R || ATARI || POWERPC)
+ || M32R || ATARI || POWERPC || MIPS)
help
Say "yes" here to get direct support for the real time clock
found in every PC or ACPI-based system, and some other boards.
@@ -397,7 +397,7 @@ config RTC_DRV_BFIN
config RTC_DRV_RS5C313
tristate "Ricoh RS5C313"
- depends on RTC_CLASS && BROKEN
+ depends on RTC_CLASS && SH_LANDISK
help
If you say yes here you get support for the Ricoh RS5C313 RTC chips.
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c
index 9d6de371495..66eb133bf5f 100644
--- a/drivers/rtc/rtc-rs5c313.c
+++ b/drivers/rtc/rtc-rs5c313.c
@@ -126,7 +126,7 @@ static void rs5c313_write_data(unsigned char data)
static unsigned char rs5c313_read_data(void)
{
int i;
- unsigned char data;
+ unsigned char data = 0;
for (i = 0; i < 8; i++) {
ndelay(700);
@@ -194,7 +194,7 @@ static void rs5c313_write_reg(unsigned char addr, unsigned char data)
return;
}
-static inline unsigned char rs5c313_read_cntreg(unsigned char addr)
+static inline unsigned char rs5c313_read_cntreg(void)
{
return rs5c313_read_reg(RS5C313_ADDR_CNTREG);
}
@@ -212,7 +212,9 @@ static inline void rs5c313_write_intintvreg(unsigned char data)
static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
int data;
+ int cnt;
+ cnt = 0;
while (1) {
RS5C313_CEENABLE; /* CE:H */
@@ -225,6 +227,10 @@ static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm)
RS5C313_CEDISABLE;
ndelay(700); /* CE:L */
+ if (cnt++ > 100) {
+ dev_err(dev, "%s: timeout error\n", __FUNCTION__);
+ return -EIO;
+ }
}
data = rs5c313_read_reg(RS5C313_ADDR_SEC);
@@ -266,7 +272,9 @@ static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
int data;
+ int cnt;
+ cnt = 0;
/* busy check. */
while (1) {
RS5C313_CEENABLE; /* CE:H */
@@ -279,6 +287,11 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
RS5C313_MISCOP;
RS5C313_CEDISABLE;
ndelay(700); /* CE:L */
+
+ if (cnt++ > 100) {
+ dev_err(dev, "%s: timeout error\n", __FUNCTION__);
+ return -EIO;
+ }
}
data = BIN2BCD(tm->tm_sec);
@@ -317,6 +330,7 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
static void rs5c313_check_xstp_bit(void)
{
struct rtc_time tm;
+ int cnt;
RS5C313_CEENABLE; /* CE:H */
if (rs5c313_read_cntreg() & RS5C313_CNTREG_WTEN_XSTP) {
@@ -326,12 +340,16 @@ static void rs5c313_check_xstp_bit(void)
rs5c313_write_cntreg(0x07);
/* busy check. */
- while (rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)
+ for (cnt = 0; cnt < 100; cnt++) {
+ if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
+ break;
RS5C313_MISCOP;
+ }
memset(&tm, 0, sizeof(struct rtc_time));
tm.tm_mday = 1;
- tm.tm_mon = 1;
+ tm.tm_mon = 1 - 1;
+ tm.tm_year = 2000 - 1900;
rs5c313_rtc_set_time(NULL, &tm);
printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to "
@@ -356,7 +374,7 @@ static int rs5c313_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rtc);
- return err;
+ return 0;
}
static int __devexit rs5c313_rtc_remove(struct platform_device *pdev)
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index f2be2ead874..8328acab47f 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -30,6 +30,7 @@
#include <asm/ebus.h>
#include <asm/uaccess.h>
#include <asm/envctrl.h>
+#include <asm/io.h>
#define ENVCTRL_MINOR 162
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index a15752b3799..eef82758d04 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -6,87 +6,49 @@
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
* Copyright (C) 2001 Florian Lohoff (flo@rfc822.org)
- * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org)
*
* (In all truth, Jed Schimmel wrote all this code.)
*/
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/blkdev.h>
+
+#undef DEBUG
+
#include <linux/delay.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/spinlock.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/sgialib.h>
-#include <asm/sgi/sgi.h>
-#include <asm/sgi/mc.h>
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
-#include <asm/irq.h>
-#include <asm/io.h>
+#include <asm/sgi/wd.h>
#include "scsi.h"
-#include <scsi/scsi_host.h>
#include "wd33c93.h"
-#include <linux/stat.h>
-
-#if 0
-#define DPRINTK(args...) printk(args)
-#else
-#define DPRINTK(args...)
-#endif
-
-#define HDATA(ptr) ((struct ip22_hostdata *)((ptr)->hostdata))
-
struct ip22_hostdata {
struct WD33C93_hostdata wh;
struct hpc_data {
dma_addr_t dma;
- void * cpu;
+ void *cpu;
} hd;
};
+#define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata))
+
struct hpc_chunk {
struct hpc_dma_desc desc;
u32 _padding; /* align to quadword boundary */
};
-struct Scsi_Host *sgiwd93_host;
-struct Scsi_Host *sgiwd93_host1;
-
-/* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */
-static inline void write_wd33c93_count(const wd33c93_regs regs,
- unsigned long value)
-{
- *regs.SASR = WD_TRANSFER_COUNT_MSB;
- mb();
- *regs.SCMD = ((value >> 16) & 0xff);
- *regs.SCMD = ((value >> 8) & 0xff);
- *regs.SCMD = ((value >> 0) & 0xff);
- mb();
-}
-
-static inline unsigned long read_wd33c93_count(const wd33c93_regs regs)
-{
- unsigned long value;
-
- *regs.SASR = WD_TRANSFER_COUNT_MSB;
- mb();
- value = ((*regs.SCMD & 0xff) << 16);
- value |= ((*regs.SCMD & 0xff) << 8);
- value |= ((*regs.SCMD & 0xff) << 0);
- mb();
- return value;
-}
-
static irqreturn_t sgiwd93_intr(int irq, void *dev_id)
{
- struct Scsi_Host * host = (struct Scsi_Host *) dev_id;
+ struct Scsi_Host * host = dev_id;
unsigned long flags;
spin_lock_irqsave(host->host_lock, flags);
@@ -131,12 +93,12 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp)
static int dma_setup(struct scsi_cmnd *cmd, int datainp)
{
- struct ip22_hostdata *hdata = HDATA(cmd->device->host);
+ struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host);
struct hpc3_scsiregs *hregs =
(struct hpc3_scsiregs *) cmd->device->host->base;
struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu;
- DPRINTK("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp);
+ pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp);
hdata->wh.dma_dir = datainp;
@@ -151,7 +113,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp)
fill_hpc_entries(hcp, cmd, datainp);
- DPRINTK(" HPCGO\n");
+ pr_debug(" HPCGO\n");
/* Start up the HPC. */
hregs->ndptr = hdata->hd.dma;
@@ -166,7 +128,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp)
static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
int status)
{
- struct ip22_hostdata *hdata = HDATA(instance);
+ struct ip22_hostdata *hdata = host_to_hostdata(instance);
struct hpc3_scsiregs *hregs;
if (!SCpnt)
@@ -174,7 +136,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base;
- DPRINTK("dma_stop: status<%d> ", status);
+ pr_debug("dma_stop: status<%d> ", status);
/* First stop the HPC and flush it's FIFO. */
if (hdata->wh.dma_dir) {
@@ -186,7 +148,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual,
SCpnt->sc_data_direction);
- DPRINTK("\n");
+ pr_debug("\n");
}
void sgiwd93_reset(unsigned long base)
@@ -216,29 +178,71 @@ static inline void init_hpc_chain(struct hpc_data *hd)
hcp->desc.pnext = hd->dma;
}
-static struct Scsi_Host * __init sgiwd93_setup_scsi(
- struct scsi_host_template *SGIblows, int unit, int irq,
- struct hpc3_scsiregs *hregs, unsigned char *wdregs)
+static int sgiwd93_bus_reset(struct scsi_cmnd *cmd)
+{
+ /* FIXME perform bus-specific reset */
+
+ /* FIXME 2: kill this function, and let midlayer fallback
+ to the same result, calling wd33c93_host_reset() */
+
+ spin_lock_irq(cmd->device->host->host_lock);
+ wd33c93_host_reset(cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
+ return SUCCESS;
+}
+
+/*
+ * Kludge alert - the SCSI code calls the abort and reset method with int
+ * arguments not with pointers. So this is going to blow up beautyfully
+ * on 64-bit systems with memory outside the compat address spaces.
+ */
+static struct scsi_host_template sgiwd93_template = {
+ .module = THIS_MODULE,
+ .proc_name = "SGIWD93",
+ .name = "SGI WD93",
+ .queuecommand = wd33c93_queuecommand,
+ .eh_abort_handler = wd33c93_abort,
+ .eh_bus_reset_handler = sgiwd93_bus_reset,
+ .eh_host_reset_handler = wd33c93_host_reset,
+ .can_queue = 16,
+ .this_id = 7,
+ .sg_tablesize = SG_ALL,
+ .cmd_per_lun = 8,
+ .use_clustering = DISABLE_CLUSTERING,
+};
+
+static int __init sgiwd93_probe(struct platform_device *pdev)
{
+ struct sgiwd93_platform_data *pd = pdev->dev.platform_data;
+ unsigned char *wdregs = pd->wdregs;
+ struct hpc3_scsiregs *hregs = pd->hregs;
struct ip22_hostdata *hdata;
struct Scsi_Host *host;
wd33c93_regs regs;
-
- host = scsi_register(SGIblows, sizeof(struct ip22_hostdata));
- if (!host)
- return NULL;
+ unsigned int unit = pd->unit;
+ unsigned int irq = pd->irq;
+ int err;
+
+ host = scsi_host_alloc(&sgiwd93_template, sizeof(struct ip22_hostdata));
+ if (!host) {
+ err = -ENOMEM;
+ goto out;
+ }
host->base = (unsigned long) hregs;
host->irq = irq;
- hdata = HDATA(host);
- hdata->hd.cpu = dma_alloc_coherent(NULL, PAGE_SIZE, &hdata->hd.dma,
- GFP_KERNEL);
+ hdata = host_to_hostdata(host);
+ hdata->hd.cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
+ &hdata->hd.dma, GFP_KERNEL);
if (!hdata->hd.cpu) {
printk(KERN_WARNING "sgiwd93: Could not allocate memory for "
"host %d buffer.\n", unit);
- goto out_unregister;
+ err = -ENOMEM;
+ goto out_put;
}
+
init_hpc_chain(&hdata->hd);
regs.SASR = wdregs + 3;
@@ -249,95 +253,67 @@ static struct Scsi_Host * __init sgiwd93_setup_scsi(
if (hdata->wh.no_sync == 0xff)
hdata->wh.no_sync = 0;
- if (request_irq(irq, sgiwd93_intr, 0, "SGI WD93", (void *) host)) {
+ err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host);
+ if (err) {
printk(KERN_WARNING "sgiwd93: Could not register irq %d "
"for host %d.\n", irq, unit);
goto out_free;
}
- return host;
-out_free:
- dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma);
- wd33c93_release();
+ platform_set_drvdata(pdev, host);
-out_unregister:
- scsi_unregister(host);
+ err = scsi_add_host(host, NULL);
+ if (err)
+ goto out_irq;
- return NULL;
-}
-
-static int __init sgiwd93_detect(struct scsi_host_template *SGIblows)
-{
- int found = 0;
-
- SGIblows->proc_name = "SGIWD93";
- sgiwd93_host = sgiwd93_setup_scsi(SGIblows, 0, SGI_WD93_0_IRQ,
- &hpc3c0->scsi_chan0,
- (unsigned char *)hpc3c0->scsi0_ext);
- if (sgiwd93_host)
- found++;
-
- /* Set up second controller on the Indigo2 */
- if (ip22_is_fullhouse()) {
- sgiwd93_host1 = sgiwd93_setup_scsi(SGIblows, 1, SGI_WD93_1_IRQ,
- &hpc3c0->scsi_chan1,
- (unsigned char *)hpc3c0->scsi1_ext);
- if (sgiwd93_host1)
- found++;
- }
-
- return found;
-}
+ scsi_scan_host(host);
-static int sgiwd93_release(struct Scsi_Host *instance)
-{
- struct ip22_hostdata *hdata = HDATA(instance);
- int irq = 0;
-
- if (sgiwd93_host && sgiwd93_host == instance)
- irq = SGI_WD93_0_IRQ;
- else if (sgiwd93_host1 && sgiwd93_host1 == instance)
- irq = SGI_WD93_1_IRQ;
+ return 0;
- free_irq(irq, sgiwd93_intr);
+out_irq:
+ free_irq(irq, host);
+out_free:
dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma);
- wd33c93_release();
+out_put:
+ scsi_host_put(host);
+out:
- return 1;
+ return err;
}
-static int sgiwd93_bus_reset(struct scsi_cmnd *cmd)
+static void __exit sgiwd93_remove(struct platform_device *pdev)
{
- /* FIXME perform bus-specific reset */
+ struct Scsi_Host *host = platform_get_drvdata(pdev);
+ struct ip22_hostdata *hdata = (struct ip22_hostdata *) host->hostdata;
+ struct sgiwd93_platform_data *pd = pdev->dev.platform_data;
+
+ scsi_remove_host(host);
+ free_irq(pd->irq, host);
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma);
+ scsi_host_put(host);
+}
- /* FIXME 2: kill this function, and let midlayer fallback
- to the same result, calling wd33c93_host_reset() */
+static struct platform_driver sgiwd93_driver = {
+ .probe = sgiwd93_probe,
+ .remove = __devexit_p(sgiwd93_remove),
+ .driver = {
+ .name = "sgiwd93"
+ }
+};
- spin_lock_irq(cmd->device->host->host_lock);
- wd33c93_host_reset(cmd);
- spin_unlock_irq(cmd->device->host->host_lock);
+static int __init sgiwd93_module_init(void)
+{
+ return platform_driver_register(&sgiwd93_driver);
+}
- return SUCCESS;
+static void __exit sgiwd93_module_exit(void)
+{
+ return platform_driver_unregister(&sgiwd93_driver);
}
-/*
- * Kludge alert - the SCSI code calls the abort and reset method with int
- * arguments not with pointers. So this is going to blow up beautyfully
- * on 64-bit systems with memory outside the compat address spaces.
- */
-static struct scsi_host_template driver_template = {
- .proc_name = "SGIWD93",
- .name = "SGI WD93",
- .detect = sgiwd93_detect,
- .release = sgiwd93_release,
- .queuecommand = wd33c93_queuecommand,
- .eh_abort_handler = wd33c93_abort,
- .eh_bus_reset_handler = sgiwd93_bus_reset,
- .eh_host_reset_handler = wd33c93_host_reset,
- .can_queue = 16,
- .this_id = 7,
- .sg_tablesize = SG_ALL,
- .cmd_per_lun = 8,
- .use_clustering = DISABLE_CLUSTERING,
-};
-#include "scsi_module.c"
+module_init(sgiwd93_module_init);
+module_exit(sgiwd93_module_exit);
+
+MODULE_DESCRIPTION("SGI WD33C93 driver");
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 7c9d37f651e..5e3f748f269 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -107,6 +107,13 @@ config SPI_IMX
This enables using the Freescale iMX SPI controller in master
mode.
+config SPI_MPC52xx_PSC
+ tristate "Freescale MPC52xx PSC SPI controller"
+ depends on SPI_MASTER && PPC_MPC52xx && EXPERIMENTAL
+ help
+ This enables using the Freescale MPC52xx Programmable Serial
+ Controller in master SPI mode.
+
config SPI_MPC83xx
tristate "Freescale MPC83xx SPI controller"
depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 624b6363f49..5788d867de8 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
obj-$(CONFIG_SPI_IMX) += spi_imx.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
+obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o
obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
new file mode 100644
index 00000000000..052359fc41e
--- /dev/null
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -0,0 +1,654 @@
+/*
+ * MPC52xx SPC in SPI mode driver.
+ *
+ * Maintainer: Dragos Carp
+ *
+ * Copyright (C) 2006 TOPTICA Photonics AG.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+#if defined(CONFIG_PPC_MERGE)
+#include <asm/of_platform.h>
+#else
+#include <linux/platform_device.h>
+#endif
+
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/mpc52xx.h>
+#include <asm/mpc52xx_psc.h>
+
+#define MCLK 20000000 /* PSC port MClk in hz */
+
+struct mpc52xx_psc_spi {
+ /* fsl_spi_platform data */
+ void (*activate_cs)(u8, u8);
+ void (*deactivate_cs)(u8, u8);
+ u32 sysclk;
+
+ /* driver internal data */
+ struct mpc52xx_psc __iomem *psc;
+ unsigned int irq;
+ u8 bits_per_word;
+ u8 busy;
+
+ struct workqueue_struct *workqueue;
+ struct work_struct work;
+
+ struct list_head queue;
+ spinlock_t lock;
+
+ struct completion done;
+};
+
+/* controller state */
+struct mpc52xx_psc_spi_cs {
+ int bits_per_word;
+ int speed_hz;
+};
+
+/* set clock freq, clock ramp, bits per work
+ * if t is NULL then reset the values to the default values
+ */
+static int mpc52xx_psc_spi_transfer_setup(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
+
+ cs->speed_hz = (t && t->speed_hz)
+ ? t->speed_hz : spi->max_speed_hz;
+ cs->bits_per_word = (t && t->bits_per_word)
+ ? t->bits_per_word : spi->bits_per_word;
+ cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8;
+ return 0;
+}
+
+static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)
+{
+ struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
+ struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
+ struct mpc52xx_psc __iomem *psc = mps->psc;
+ u32 sicr;
+ u16 ccr;
+
+ sicr = in_be32(&psc->sicr);
+
+ /* Set clock phase and polarity */
+ if (spi->mode & SPI_CPHA)
+ sicr |= 0x00001000;
+ else
+ sicr &= ~0x00001000;
+ if (spi->mode & SPI_CPOL)
+ sicr |= 0x00002000;
+ else
+ sicr &= ~0x00002000;
+
+ if (spi->mode & SPI_LSB_FIRST)
+ sicr |= 0x10000000;
+ else
+ sicr &= ~0x10000000;
+ out_be32(&psc->sicr, sicr);
+
+ /* Set clock frequency and bits per word
+ * Because psc->ccr is defined as 16bit register instead of 32bit
+ * just set the lower byte of BitClkDiv
+ */
+ ccr = in_be16(&psc->ccr);
+ ccr &= 0xFF00;
+ if (cs->speed_hz)
+ ccr |= (MCLK / cs->speed_hz - 1) & 0xFF;
+ else /* by default SPI Clk 1MHz */
+ ccr |= (MCLK / 1000000 - 1) & 0xFF;
+ out_be16(&psc->ccr, ccr);
+ mps->bits_per_word = cs->bits_per_word;
+
+ if (mps->activate_cs)
+ mps->activate_cs(spi->chip_select,
+ (spi->mode & SPI_CS_HIGH) ? 1 : 0);
+}
+
+static void mpc52xx_psc_spi_deactivate_cs(struct spi_device *spi)
+{
+ struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
+
+ if (mps->deactivate_cs)
+ mps->deactivate_cs(spi->chip_select,
+ (spi->mode & SPI_CS_HIGH) ? 1 : 0);
+}
+
+#define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1)
+/* wake up when 80% fifo full */
+#define MPC52xx_PSC_RFALARM (MPC52xx_PSC_BUFSIZE * 20 / 100)
+
+static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
+ struct mpc52xx_psc __iomem *psc = mps->psc;
+ unsigned rb = 0; /* number of bytes receieved */
+ unsigned sb = 0; /* number of bytes sent */
+ unsigned char *rx_buf = (unsigned char *)t->rx_buf;
+ unsigned char *tx_buf = (unsigned char *)t->tx_buf;
+ unsigned rfalarm;
+ unsigned send_at_once = MPC52xx_PSC_BUFSIZE;
+ unsigned recv_at_once;
+ unsigned bpw = mps->bits_per_word / 8;
+
+ if (!t->tx_buf && !t->rx_buf && t->len)
+ return -EINVAL;
+
+ /* enable transmiter/receiver */
+ out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
+ while (rb < t->len) {
+ if (t->len - rb > MPC52xx_PSC_BUFSIZE) {
+ rfalarm = MPC52xx_PSC_RFALARM;
+ } else {
+ send_at_once = t->len - sb;
+ rfalarm = MPC52xx_PSC_BUFSIZE - (t->len - rb);
+ }
+
+ dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once);
+ if (tx_buf) {
+ for (; send_at_once; sb++, send_at_once--) {
+ /* set EOF flag */
+ if (mps->bits_per_word
+ && (sb + 1) % bpw == 0)
+ out_8(&psc->ircr2, 0x01);
+ out_8(&psc->mpc52xx_psc_buffer_8, tx_buf[sb]);
+ }
+ } else {
+ for (; send_at_once; sb++, send_at_once--) {
+ /* set EOF flag */
+ if (mps->bits_per_word
+ && ((sb + 1) % bpw) == 0)
+ out_8(&psc->ircr2, 0x01);
+ out_8(&psc->mpc52xx_psc_buffer_8, 0);
+ }
+ }
+
+
+ /* enable interupts and wait for wake up
+ * if just one byte is expected the Rx FIFO genererates no
+ * FFULL interrupt, so activate the RxRDY interrupt
+ */
+ out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
+ if (t->len - rb == 1) {
+ out_8(&psc->mode, 0);
+ } else {
+ out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
+ out_be16(&psc->rfalarm, rfalarm);
+ }
+ out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY);
+ wait_for_completion(&mps->done);
+ recv_at_once = in_be16(&psc->rfnum);
+ dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once);
+
+ send_at_once = recv_at_once;
+ if (rx_buf) {
+ for (; recv_at_once; rb++, recv_at_once--)
+ rx_buf[rb] = in_8(&psc->mpc52xx_psc_buffer_8);
+ } else {
+ for (; recv_at_once; rb++, recv_at_once--)
+ in_8(&psc->mpc52xx_psc_buffer_8);
+ }
+ }
+ /* disable transmiter/receiver */
+ out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
+
+ return 0;
+}
+
+static void mpc52xx_psc_spi_work(struct work_struct *work)
+{
+ struct mpc52xx_psc_spi *mps =
+ container_of(work, struct mpc52xx_psc_spi, work);
+
+ spin_lock_irq(&mps->lock);
+ mps->busy = 1;
+ while (!list_empty(&mps->queue)) {
+ struct spi_message *m;
+ struct spi_device *spi;
+ struct spi_transfer *t = NULL;
+ unsigned cs_change;
+ int status;
+
+ m = container_of(mps->queue.next, struct spi_message, queue);
+ list_del_init(&m->queue);
+ spin_unlock_irq(&mps->lock);
+
+ spi = m->spi;
+ cs_change = 1;
+ status = 0;
+ list_for_each_entry (t, &m->transfers, transfer_list) {
+ if (t->bits_per_word || t->speed_hz) {
+ status = mpc52xx_psc_spi_transfer_setup(spi, t);
+ if (status < 0)
+ break;
+ }
+
+ if (cs_change)
+ mpc52xx_psc_spi_activate_cs(spi);
+ cs_change = t->cs_change;
+
+ status = mpc52xx_psc_spi_transfer_rxtx(spi, t);
+ if (status)
+ break;
+ m->actual_length += t->len;
+
+ if (t->delay_usecs)
+ udelay(t->delay_usecs);
+
+ if (cs_change)
+ mpc52xx_psc_spi_deactivate_cs(spi);
+ }
+
+ m->status = status;
+ m->complete(m->context);
+
+ if (status || !cs_change)
+ mpc52xx_psc_spi_deactivate_cs(spi);
+
+ mpc52xx_psc_spi_transfer_setup(spi, NULL);
+
+ spin_lock_irq(&mps->lock);
+ }
+ mps->busy = 0;
+ spin_unlock_irq(&mps->lock);
+}
+
+static int mpc52xx_psc_spi_setup(struct spi_device *spi)
+{
+ struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
+ struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
+ unsigned long flags;
+
+ if (spi->bits_per_word%8)
+ return -EINVAL;
+
+ if (!cs) {
+ cs = kzalloc(sizeof *cs, GFP_KERNEL);
+ if (!cs)
+ return -ENOMEM;
+ spi->controller_state = cs;
+ }
+
+ cs->bits_per_word = spi->bits_per_word;
+ cs->speed_hz = spi->max_speed_hz;
+
+ spin_lock_irqsave(&mps->lock, flags);
+ if (!mps->busy)
+ mpc52xx_psc_spi_deactivate_cs(spi);
+ spin_unlock_irqrestore(&mps->lock, flags);
+
+ return 0;
+}
+
+static int mpc52xx_psc_spi_transfer(struct spi_device *spi,
+ struct spi_message *m)
+{
+ struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
+ unsigned long flags;
+
+ m->actual_length = 0;
+ m->status = -EINPROGRESS;
+
+ spin_lock_irqsave(&mps->lock, flags);
+ list_add_tail(&m->queue, &mps->queue);
+ queue_work(mps->workqueue, &mps->work);
+ spin_unlock_irqrestore(&mps->lock, flags);
+
+ return 0;
+}
+
+static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)
+{
+ kfree(spi->controller_state);
+}
+
+static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
+{
+ struct mpc52xx_cdm __iomem *cdm;
+ struct mpc52xx_gpio __iomem *gpio;
+ struct mpc52xx_psc __iomem *psc = mps->psc;
+ u32 ul;
+ u32 mclken_div;
+ int ret = 0;
+
+#if defined(CONFIG_PPC_MERGE)
+ cdm = mpc52xx_find_and_map("mpc52xx-cdm");
+ gpio = mpc52xx_find_and_map("mpc52xx-gpio");
+#else
+ cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
+ gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
+#endif
+ if (!cdm || !gpio) {
+ printk(KERN_ERR "Error mapping CDM/GPIO\n");
+ ret = -EFAULT;
+ goto unmap_regs;
+ }
+
+ /* default sysclk is 512MHz */
+ mclken_div = 0x8000 |
+ (((mps->sysclk ? mps->sysclk : 512000000) / MCLK) & 0x1FF);
+
+ switch (psc_id) {
+ case 1:
+ ul = in_be32(&gpio->port_config);
+ ul &= 0xFFFFFFF8;
+ ul |= 0x00000006;
+ out_be32(&gpio->port_config, ul);
+ out_be16(&cdm->mclken_div_psc1, mclken_div);
+ ul = in_be32(&cdm->clk_enables);
+ ul |= 0x00000020;
+ out_be32(&cdm->clk_enables, ul);
+ break;
+ case 2:
+ ul = in_be32(&gpio->port_config);
+ ul &= 0xFFFFFF8F;
+ ul |= 0x00000060;
+ out_be32(&gpio->port_config, ul);
+ out_be16(&cdm->mclken_div_psc2, mclken_div);
+ ul = in_be32(&cdm->clk_enables);
+ ul |= 0x00000040;
+ out_be32(&cdm->clk_enables, ul);
+ break;
+ case 3:
+ ul = in_be32(&gpio->port_config);
+ ul &= 0xFFFFF0FF;
+ ul |= 0x00000600;
+ out_be32(&gpio->port_config, ul);
+ out_be16(&cdm->mclken_div_psc3, mclken_div);
+ ul = in_be32(&cdm->clk_enables);
+ ul |= 0x00000080;
+ out_be32(&cdm->clk_enables, ul);
+ break;
+ case 6:
+ ul = in_be32(&gpio->port_config);
+ ul &= 0xFF8FFFFF;
+ ul |= 0x00700000;
+ out_be32(&gpio->port_config, ul);
+ out_be16(&cdm->mclken_div_psc6, mclken_div);
+ ul = in_be32(&cdm->clk_enables);
+ ul |= 0x00000010;
+ out_be32(&cdm->clk_enables, ul);
+ break;
+ default:
+ ret = -EINVAL;
+ goto unmap_regs;
+ }
+
+ /* Reset the PSC into a known state */
+ out_8(&psc->command, MPC52xx_PSC_RST_RX);
+ out_8(&psc->command, MPC52xx_PSC_RST_TX);
+ out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
+
+ /* Disable interrupts, interrupts are based on alarm level */
+ out_be16(&psc->mpc52xx_psc_imr, 0);
+ out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
+ out_8(&psc->rfcntl, 0);
+ out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
+
+ /* Configure 8bit codec mode as a SPI master and use EOF flags */
+ /* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */
+ out_be32(&psc->sicr, 0x0180C800);
+ out_be16(&psc->ccr, 0x070F); /* by default SPI Clk 1MHz */
+
+ /* Set 2ms DTL delay */
+ out_8(&psc->ctur, 0x00);
+ out_8(&psc->ctlr, 0x84);
+
+ mps->bits_per_word = 8;
+
+unmap_regs:
+ if (cdm)
+ iounmap(cdm);
+ if (gpio)
+ iounmap(gpio);
+
+ return ret;
+}
+
+static irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id)
+{
+ struct mpc52xx_psc_spi *mps = (struct mpc52xx_psc_spi *)dev_id;
+ struct mpc52xx_psc __iomem *psc = mps->psc;
+
+ /* disable interrupt and wake up the work queue */
+ if (in_be16(&psc->mpc52xx_psc_isr) & MPC52xx_PSC_IMR_RXRDY) {
+ out_be16(&psc->mpc52xx_psc_imr, 0);
+ complete(&mps->done);
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
+/* bus_num is used only for the case dev->platform_data == NULL */
+static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
+ u32 size, unsigned int irq, s16 bus_num)
+{
+ struct fsl_spi_platform_data *pdata = dev->platform_data;
+ struct mpc52xx_psc_spi *mps;
+ struct spi_master *master;
+ int ret;
+
+ if (pdata == NULL)
+ return -ENODEV;
+
+ master = spi_alloc_master(dev, sizeof *mps);
+ if (master == NULL)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, master);
+ mps = spi_master_get_devdata(master);
+
+ mps->irq = irq;
+ if (pdata == NULL) {
+ dev_warn(dev, "probe called without platform data, no "
+ "(de)activate_cs function will be called\n");
+ mps->activate_cs = NULL;
+ mps->deactivate_cs = NULL;
+ mps->sysclk = 0;
+ master->bus_num = bus_num;
+ master->num_chipselect = 255;
+ } else {
+ mps->activate_cs = pdata->activate_cs;
+ mps->deactivate_cs = pdata->deactivate_cs;
+ mps->sysclk = pdata->sysclk;
+ master->bus_num = pdata->bus_num;
+ master->num_chipselect = pdata->max_chipselect;
+ }
+ master->setup = mpc52xx_psc_spi_setup;
+ master->transfer = mpc52xx_psc_spi_transfer;
+ master->cleanup = mpc52xx_psc_spi_cleanup;
+
+ mps->psc = ioremap(regaddr, size);
+ if (!mps->psc) {
+ dev_err(dev, "could not ioremap I/O port range\n");
+ ret = -EFAULT;
+ goto free_master;
+ }
+
+ ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi",
+ mps);
+ if (ret)
+ goto free_master;
+
+ ret = mpc52xx_psc_spi_port_config(master->bus_num, mps);
+ if (ret < 0)
+ goto free_irq;
+
+ spin_lock_init(&mps->lock);
+ init_completion(&mps->done);
+ INIT_WORK(&mps->work, mpc52xx_psc_spi_work);
+ INIT_LIST_HEAD(&mps->queue);
+
+ mps->workqueue = create_singlethread_workqueue(
+ master->cdev.dev->bus_id);
+ if (mps->workqueue == NULL) {
+ ret = -EBUSY;
+ goto free_irq;
+ }
+
+ ret = spi_register_master(master);
+ if (ret < 0)
+ goto unreg_master;
+
+ return ret;
+
+unreg_master:
+ destroy_workqueue(mps->workqueue);
+free_irq:
+ free_irq(mps->irq, mps);
+free_master:
+ if (mps->psc)
+ iounmap(mps->psc);
+ spi_master_put(master);
+
+ return ret;
+}
+
+static int __exit mpc52xx_psc_spi_do_remove(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master);
+
+ flush_workqueue(mps->workqueue);
+ destroy_workqueue(mps->workqueue);
+ spi_unregister_master(master);
+ free_irq(mps->irq, mps);
+ if (mps->psc)
+ iounmap(mps->psc);
+
+ return 0;
+}
+
+#if !defined(CONFIG_PPC_MERGE)
+static int __init mpc52xx_psc_spi_probe(struct platform_device *dev)
+{
+ switch(dev->id) {
+ case 1:
+ case 2:
+ case 3:
+ case 6:
+ return mpc52xx_psc_spi_do_probe(&dev->dev,
+ MPC52xx_PA(MPC52xx_PSCx_OFFSET(dev->id)),
+ MPC52xx_PSC_SIZE, platform_get_irq(dev, 0), dev->id);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int __exit mpc52xx_psc_spi_remove(struct platform_device *dev)
+{
+ return mpc52xx_psc_spi_do_remove(&dev->dev);
+}
+
+static struct platform_driver mpc52xx_psc_spi_platform_driver = {
+ .remove = __exit_p(mpc52xx_psc_spi_remove),
+ .driver = {
+ .name = "mpc52xx-psc-spi",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mpc52xx_psc_spi_init(void)
+{
+ return platform_driver_probe(&mpc52xx_psc_spi_platform_driver,
+ mpc52xx_psc_spi_probe);
+}
+module_init(mpc52xx_psc_spi_init);
+
+static void __exit mpc52xx_psc_spi_exit(void)
+{
+ platform_driver_unregister(&mpc52xx_psc_spi_platform_driver);
+}
+module_exit(mpc52xx_psc_spi_exit);
+
+#else /* defined(CONFIG_PPC_MERGE) */
+
+static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
+ const struct of_device_id *match)
+{
+ const u32 *regaddr_p;
+ u64 regaddr64, size64;
+ s16 id = -1;
+
+ regaddr_p = of_get_address(op->node, 0, &size64, NULL);
+ if (!regaddr_p) {
+ printk(KERN_ERR "Invalid PSC address\n");
+ return -EINVAL;
+ }
+ regaddr64 = of_translate_address(op->node, regaddr_p);
+
+ if (op->dev.platform_data == NULL) {
+ struct device_node *np;
+ int i = 0;
+
+ for_each_node_by_type(np, "spi") {
+ if (of_find_device_by_node(np) == op) {
+ id = i;
+ break;
+ }
+ i++;
+ }
+ }
+
+ return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
+ irq_of_parse_and_map(op->node, 0), id);
+}
+
+static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op)
+{
+ return mpc52xx_psc_spi_do_remove(&op->dev);
+}
+
+static struct of_device_id mpc52xx_psc_spi_of_match[] = {
+ { .type = "spi", .compatible = "mpc52xx-psc-spi", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match);
+
+static struct of_platform_driver mpc52xx_psc_spi_of_driver = {
+ .owner = THIS_MODULE,
+ .name = "mpc52xx-psc-spi",
+ .match_table = mpc52xx_psc_spi_of_match,
+ .probe = mpc52xx_psc_spi_of_probe,
+ .remove = __exit_p(mpc52xx_psc_spi_of_remove),
+ .driver = {
+ .name = "mpc52xx-psc-spi",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mpc52xx_psc_spi_init(void)
+{
+ return of_register_platform_driver(&mpc52xx_psc_spi_of_driver);
+}
+module_init(mpc52xx_psc_spi_init);
+
+static void __exit mpc52xx_psc_spi_exit(void)
+{
+ of_unregister_platform_driver(&mpc52xx_psc_spi_of_driver);
+}
+module_exit(mpc52xx_psc_spi_exit);
+
+#endif /* defined(CONFIG_PPC_MERGE) */
+
+MODULE_AUTHOR("Dragos Carp");
+MODULE_DESCRIPTION("MPC52xx PSC SPI Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f54438828cb..eebcb708cff 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -748,6 +748,22 @@ config FB_S1D13XXX
working with S1D13806). Product specs at
<http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+config FB_ATMEL
+ tristate "AT91/AT32 LCD Controller support"
+ depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || AVR32)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This enables support for the AT91/AT32 LCD Controller.
+
+config FB_INTSRAM
+ bool "Frame Buffer in internal SRAM"
+ depends on FB_ATMEL && ARCH_AT91SAM9261
+ help
+ Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
+ to let frame buffer in external SDRAM.
+
config FB_NVIDIA
tristate "nVidia Framebuffer Support"
depends on FB && PCI
@@ -780,6 +796,15 @@ config FB_NVIDIA_I2C
independently validate video mode parameters, you should say Y
here.
+config FB_NVIDIA_DEBUG
+ bool "Lots of debug output"
+ depends on FB_NVIDIA
+ default n
+ help
+ Say Y here if you want the nVidia driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
config FB_NVIDIA_BACKLIGHT
bool "Support for backlight control"
depends on FB_NVIDIA
@@ -819,7 +844,7 @@ config FB_RIVA_I2C
here.
config FB_RIVA_DEBUG
- bool "Lots of debug output from Riva(nVidia) driver"
+ bool "Lots of debug output"
depends on FB_RIVA
default n
help
@@ -1431,8 +1456,11 @@ config FB_ARK
and ICS 5342 RAMDAC.
config FB_PM3
- tristate "Permedia3 support"
- depends on FB && PCI && BROKEN
+ tristate "Permedia3 support (EXPERIMENTAL)"
+ depends on FB && PCI && EXPERIMENTAL
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
help
This is the frame buffer device driver for the 3DLabs Permedia3
chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 0b70567458f..bd8b0522950 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_FB_G364) += g364fb.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o
obj-$(CONFIG_FB_HIT) += hitfb.o
obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o
+obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
new file mode 100644
index 00000000000..e1d5bd0c98c
--- /dev/null
+++ b/drivers/video/atmel_lcdfb.c
@@ -0,0 +1,752 @@
+/*
+ * Driver for AT91/AT32 LCD Controller
+ *
+ * Copyright (C) 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/gpio.h>
+
+#include <video/atmel_lcdc.h>
+
+#define lcdc_readl(sinfo, reg) __raw_readl((sinfo)->mmio+(reg))
+#define lcdc_writel(sinfo, reg, val) __raw_writel((val), (sinfo)->mmio+(reg))
+
+/* configurable parameters */
+#define ATMEL_LCDC_CVAL_DEFAULT 0xc8
+#define ATMEL_LCDC_DMA_BURST_LEN 8
+
+#if defined(CONFIG_ARCH_AT91SAM9263)
+#define ATMEL_LCDC_FIFO_SIZE 2048
+#else
+#define ATMEL_LCDC_FIFO_SIZE 512
+#endif
+
+#if defined(CONFIG_ARCH_AT91)
+#define ATMEL_LCDFB_FBINFO_DEFAULT FBINFO_DEFAULT
+
+static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
+ struct fb_var_screeninfo *var)
+{
+
+}
+#elif defined(CONFIG_AVR32)
+#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \
+ | FBINFO_PARTIAL_PAN_OK \
+ | FBINFO_HWACCEL_XPAN \
+ | FBINFO_HWACCEL_YPAN)
+
+static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
+ struct fb_var_screeninfo *var)
+{
+ u32 dma2dcfg;
+ u32 pixeloff;
+
+ pixeloff = (var->xoffset * var->bits_per_pixel) & 0x1f;
+
+ dma2dcfg = ((var->xres_virtual - var->xres) * var->bits_per_pixel) / 8;
+ dma2dcfg |= pixeloff << ATMEL_LCDC_PIXELOFF_OFFSET;
+ lcdc_writel(sinfo, ATMEL_LCDC_DMA2DCFG, dma2dcfg);
+
+ /* Update configuration */
+ lcdc_writel(sinfo, ATMEL_LCDC_DMACON,
+ lcdc_readl(sinfo, ATMEL_LCDC_DMACON)
+ | ATMEL_LCDC_DMAUPDT);
+}
+#endif
+
+
+static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
+};
+
+
+static void atmel_lcdfb_update_dma(struct fb_info *info,
+ struct fb_var_screeninfo *var)
+{
+ struct atmel_lcdfb_info *sinfo = info->par;
+ struct fb_fix_screeninfo *fix = &info->fix;
+ unsigned long dma_addr;
+
+ dma_addr = (fix->smem_start + var->yoffset * fix->line_length
+ + var->xoffset * var->bits_per_pixel / 8);
+
+ dma_addr &= ~3UL;
+
+ /* Set framebuffer DMA base address and pixel offset */
+ lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
+
+ atmel_lcdfb_update_dma2d(sinfo, var);
+}
+
+static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
+{
+ struct fb_info *info = sinfo->info;
+
+ dma_free_writecombine(info->device, info->fix.smem_len,
+ info->screen_base, info->fix.smem_start);
+}
+
+/**
+ * atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory
+ * @sinfo: the frame buffer to allocate memory for
+ */
+static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo)
+{
+ struct fb_info *info = sinfo->info;
+ struct fb_var_screeninfo *var = &info->var;
+
+ info->fix.smem_len = (var->xres_virtual * var->yres_virtual
+ * ((var->bits_per_pixel + 7) / 8));
+
+ info->screen_base = dma_alloc_writecombine(info->device, info->fix.smem_len,
+ (dma_addr_t *)&info->fix.smem_start, GFP_KERNEL);
+
+ if (!info->screen_base) {
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/**
+ * atmel_lcdfb_check_var - Validates a var passed in.
+ * @var: frame buffer variable screen structure
+ * @info: frame buffer structure that represents a single frame buffer
+ *
+ * Checks to see if the hardware supports the state requested by
+ * var passed in. This function does not alter the hardware
+ * state!!! This means the data stored in struct fb_info and
+ * struct atmel_lcdfb_info do not change. This includes the var
+ * inside of struct fb_info. Do NOT change these. This function
+ * can be called on its own if we intent to only test a mode and
+ * not actually set it. The stuff in modedb.c is a example of
+ * this. If the var passed in is slightly off by what the
+ * hardware can support then we alter the var PASSED in to what
+ * we can do. If the hardware doesn't support mode change a
+ * -EINVAL will be returned by the upper layers. You don't need
+ * to implement this function then. If you hardware doesn't
+ * support changing the resolution then this function is not
+ * needed. In this case the driver would just provide a var that
+ * represents the static state the screen is in.
+ *
+ * Returns negative errno on error, or zero on success.
+ */
+static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct device *dev = info->device;
+ struct atmel_lcdfb_info *sinfo = info->par;
+ unsigned long clk_value_khz;
+
+ clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
+
+ dev_dbg(dev, "%s:\n", __func__);
+ dev_dbg(dev, " resolution: %ux%u\n", var->xres, var->yres);
+ dev_dbg(dev, " pixclk: %lu KHz\n", PICOS2KHZ(var->pixclock));
+ dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel);
+ dev_dbg(dev, " clk: %lu KHz\n", clk_value_khz);
+
+ if ((PICOS2KHZ(var->pixclock) * var->bits_per_pixel / 8) > clk_value_khz) {
+ dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(var->pixclock));
+ return -EINVAL;
+ }
+
+ /* Force same alignment for each line */
+ var->xres = (var->xres + 3) & ~3UL;
+ var->xres_virtual = (var->xres_virtual + 3) & ~3UL;
+
+ var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
+ var->transp.offset = var->transp.length = 0;
+ var->xoffset = var->yoffset = 0;
+
+ switch (var->bits_per_pixel) {
+ case 2:
+ case 4:
+ case 8:
+ var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length
+ = var->bits_per_pixel;
+ break;
+ case 15:
+ case 16:
+ var->red.offset = 0;
+ var->green.offset = 5;
+ var->blue.offset = 10;
+ var->red.length = var->green.length = var->blue.length = 5;
+ break;
+ case 24:
+ case 32:
+ var->red.offset = 0;
+ var->green.offset = 8;
+ var->blue.offset = 16;
+ var->red.length = var->green.length = var->blue.length = 8;
+ break;
+ default:
+ dev_err(dev, "color depth %d not supported\n",
+ var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * atmel_lcdfb_set_par - Alters the hardware state.
+ * @info: frame buffer structure that represents a single frame buffer
+ *
+ * Using the fb_var_screeninfo in fb_info we set the resolution
+ * of the this particular framebuffer. This function alters the
+ * par AND the fb_fix_screeninfo stored in fb_info. It doesn't
+ * not alter var in fb_info since we are using that data. This
+ * means we depend on the data in var inside fb_info to be
+ * supported by the hardware. atmel_lcdfb_check_var is always called
+ * before atmel_lcdfb_set_par to ensure this. Again if you can't
+ * change the resolution you don't need this function.
+ *
+ */
+static int atmel_lcdfb_set_par(struct fb_info *info)
+{
+ struct atmel_lcdfb_info *sinfo = info->par;
+ unsigned long value;
+ unsigned long clk_value_khz;
+
+ dev_dbg(info->device, "%s:\n", __func__);
+ dev_dbg(info->device, " * resolution: %ux%u (%ux%u virtual)\n",
+ info->var.xres, info->var.yres,
+ info->var.xres_virtual, info->var.yres_virtual);
+
+ /* Turn off the LCD controller and the DMA controller */
+ lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
+
+ lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+
+ if (info->var.bits_per_pixel <= 8)
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ else
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+ info->fix.line_length = info->var.xres_virtual * (info->var.bits_per_pixel / 8);
+
+ /* Re-initialize the DMA engine... */
+ dev_dbg(info->device, " * update DMA engine\n");
+ atmel_lcdfb_update_dma(info, &info->var);
+
+ /* ...set frame size and burst length = 8 words (?) */
+ value = (info->var.yres * info->var.xres * info->var.bits_per_pixel) / 32;
+ value |= ((ATMEL_LCDC_DMA_BURST_LEN - 1) << ATMEL_LCDC_BLENGTH_OFFSET);
+ lcdc_writel(sinfo, ATMEL_LCDC_DMAFRMCFG, value);
+
+ /* Now, the LCDC core... */
+
+ /* Set pixel clock */
+ clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
+
+ value = clk_value_khz / PICOS2KHZ(info->var.pixclock);
+
+ if (clk_value_khz % PICOS2KHZ(info->var.pixclock))
+ value++;
+
+ value = (value / 2) - 1;
+
+ if (value <= 0) {
+ dev_notice(info->device, "Bypassing pixel clock divider\n");
+ lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
+ } else
+ lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET);
+
+ /* Initialize control register 2 */
+ value = sinfo->default_lcdcon2;
+
+ if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
+ value |= ATMEL_LCDC_INVLINE_INVERTED;
+ if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
+ value |= ATMEL_LCDC_INVFRAME_INVERTED;
+
+ switch (info->var.bits_per_pixel) {
+ case 1: value |= ATMEL_LCDC_PIXELSIZE_1; break;
+ case 2: value |= ATMEL_LCDC_PIXELSIZE_2; break;
+ case 4: value |= ATMEL_LCDC_PIXELSIZE_4; break;
+ case 8: value |= ATMEL_LCDC_PIXELSIZE_8; break;
+ case 15: /* fall through */
+ case 16: value |= ATMEL_LCDC_PIXELSIZE_16; break;
+ case 24: value |= ATMEL_LCDC_PIXELSIZE_24; break;
+ case 32: value |= ATMEL_LCDC_PIXELSIZE_32; break;
+ default: BUG(); break;
+ }
+ dev_dbg(info->device, " * LCDCON2 = %08lx\n", value);
+ lcdc_writel(sinfo, ATMEL_LCDC_LCDCON2, value);
+
+ /* Vertical timing */
+ value = (info->var.vsync_len - 1) << ATMEL_LCDC_VPW_OFFSET;
+ value |= info->var.upper_margin << ATMEL_LCDC_VBP_OFFSET;
+ value |= info->var.lower_margin;
+ dev_dbg(info->device, " * LCDTIM1 = %08lx\n", value);
+ lcdc_writel(sinfo, ATMEL_LCDC_TIM1, value);
+
+ /* Horizontal timing */
+ value = (info->var.right_margin - 1) << ATMEL_LCDC_HFP_OFFSET;
+ value |= (info->var.hsync_len - 1) << ATMEL_LCDC_HPW_OFFSET;
+ value |= (info->var.left_margin - 1);
+ dev_dbg(info->device, " * LCDTIM2 = %08lx\n", value);
+ lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value);
+
+ /* Display size */
+ value = (info->var.xres - 1) << ATMEL_LCDC_HOZVAL_OFFSET;
+ value |= info->var.yres - 1;
+ lcdc_writel(sinfo, ATMEL_LCDC_LCDFRMCFG, value);
+
+ /* FIFO Threshold: Use formula from data sheet */
+ value = ATMEL_LCDC_FIFO_SIZE - (2 * ATMEL_LCDC_DMA_BURST_LEN + 3);
+ lcdc_writel(sinfo, ATMEL_LCDC_FIFO, value);
+
+ /* Toggle LCD_MODE every frame */
+ lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0);
+
+ /* Disable all interrupts */
+ lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
+
+ /* Set contrast */
+ value = ATMEL_LCDC_PS_DIV8 | ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_ENA_PWMENABLE;
+ lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, value);
+ lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
+ /* ...wait for DMA engine to become idle... */
+ while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
+ msleep(10);
+
+ dev_dbg(info->device, " * re-enable DMA engine\n");
+ /* ...and enable it with updated configuration */
+ lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+
+ dev_dbg(info->device, " * re-enable LCDC core\n");
+ lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+ (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
+
+ dev_dbg(info->device, " * DONE\n");
+
+ return 0;
+}
+
+static inline unsigned int chan_to_field(unsigned int chan, const struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+/**
+ * atmel_lcdfb_setcolreg - Optional function. Sets a color register.
+ * @regno: Which register in the CLUT we are programming
+ * @red: The red value which can be up to 16 bits wide
+ * @green: The green value which can be up to 16 bits wide
+ * @blue: The blue value which can be up to 16 bits wide.
+ * @transp: If supported the alpha value which can be up to 16 bits wide.
+ * @info: frame buffer info structure
+ *
+ * Set a single color register. The values supplied have a 16 bit
+ * magnitude which needs to be scaled in this function for the hardware.
+ * Things to take into consideration are how many color registers, if
+ * any, are supported with the current color visual. With truecolor mode
+ * no color palettes are supported. Here a psuedo palette is created
+ * which we store the value in pseudo_palette in struct fb_info. For
+ * pseudocolor mode we have a limited color palette. To deal with this
+ * we can program what color is displayed for a particular pixel value.
+ * DirectColor is similar in that we can program each color field. If
+ * we have a static colormap we don't need to implement this function.
+ *
+ * Returns negative errno on error, or zero on success. In an
+ * ideal world, this would have been the case, but as it turns
+ * out, the other drivers return 1 on failure, so that's what
+ * we're going to do.
+ */
+static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
+ unsigned int green, unsigned int blue,
+ unsigned int transp, struct fb_info *info)
+{
+ struct atmel_lcdfb_info *sinfo = info->par;
+ unsigned int val;
+ u32 *pal;
+ int ret = 1;
+
+ if (info->var.grayscale)
+ red = green = blue = (19595 * red + 38470 * green
+ + 7471 * blue) >> 16;
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ if (regno < 16) {
+ pal = info->pseudo_palette;
+
+ val = chan_to_field(red, &info->var.red);
+ val |= chan_to_field(green, &info->var.green);
+ val |= chan_to_field(blue, &info->var.blue);
+
+ pal[regno] = val;
+ ret = 0;
+ }
+ break;
+
+ case FB_VISUAL_PSEUDOCOLOR:
+ if (regno < 256) {
+ val = ((red >> 11) & 0x001f);
+ val |= ((green >> 6) & 0x03e0);
+ val |= ((blue >> 1) & 0x7c00);
+
+ /*
+ * TODO: intensity bit. Maybe something like
+ * ~(red[10] ^ green[10] ^ blue[10]) & 1
+ */
+
+ lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
+ ret = 0;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ dev_dbg(info->device, "%s\n", __func__);
+
+ atmel_lcdfb_update_dma(info, var);
+
+ return 0;
+}
+
+static struct fb_ops atmel_lcdfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = atmel_lcdfb_check_var,
+ .fb_set_par = atmel_lcdfb_set_par,
+ .fb_setcolreg = atmel_lcdfb_setcolreg,
+ .fb_pan_display = atmel_lcdfb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static irqreturn_t atmel_lcdfb_interrupt(int irq, void *dev_id)
+{
+ struct fb_info *info = dev_id;
+ struct atmel_lcdfb_info *sinfo = info->par;
+ u32 status;
+
+ status = lcdc_readl(sinfo, ATMEL_LCDC_ISR);
+ lcdc_writel(sinfo, ATMEL_LCDC_IDR, status);
+ return IRQ_HANDLED;
+}
+
+static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo)
+{
+ struct fb_info *info = sinfo->info;
+ int ret = 0;
+
+ memset_io(info->screen_base, 0, info->fix.smem_len);
+ info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+
+ dev_info(info->device,
+ "%luKiB frame buffer at %08lx (mapped at %p)\n",
+ (unsigned long)info->fix.smem_len / 1024,
+ (unsigned long)info->fix.smem_start,
+ info->screen_base);
+
+ /* Allocate colormap */
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret < 0)
+ dev_err(info->device, "Alloc color map failed\n");
+
+ return ret;
+}
+
+static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo)
+{
+ if (sinfo->bus_clk)
+ clk_enable(sinfo->bus_clk);
+ clk_enable(sinfo->lcdc_clk);
+}
+
+static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
+{
+ if (sinfo->bus_clk)
+ clk_disable(sinfo->bus_clk);
+ clk_disable(sinfo->lcdc_clk);
+}
+
+
+static int __init atmel_lcdfb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct fb_info *info;
+ struct atmel_lcdfb_info *sinfo;
+ struct atmel_lcdfb_info *pdata_sinfo;
+ struct resource *regs = NULL;
+ struct resource *map = NULL;
+ int ret;
+
+ dev_dbg(dev, "%s BEGIN\n", __func__);
+
+ ret = -ENOMEM;
+ info = framebuffer_alloc(sizeof(struct atmel_lcdfb_info), dev);
+ if (!info) {
+ dev_err(dev, "cannot allocate memory\n");
+ goto out;
+ }
+
+ sinfo = info->par;
+
+ if (dev->platform_data) {
+ pdata_sinfo = (struct atmel_lcdfb_info *)dev->platform_data;
+ sinfo->default_bpp = pdata_sinfo->default_bpp;
+ sinfo->default_dmacon = pdata_sinfo->default_dmacon;
+ sinfo->default_lcdcon2 = pdata_sinfo->default_lcdcon2;
+ sinfo->default_monspecs = pdata_sinfo->default_monspecs;
+ sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control;
+ sinfo->guard_time = pdata_sinfo->guard_time;
+ } else {
+ dev_err(dev, "cannot get default configuration\n");
+ goto free_info;
+ }
+ sinfo->info = info;
+ sinfo->pdev = pdev;
+
+ strcpy(info->fix.id, sinfo->pdev->name);
+ info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;
+ info->pseudo_palette = sinfo->pseudo_palette;
+ info->fbops = &atmel_lcdfb_ops;
+
+ memcpy(&info->monspecs, sinfo->default_monspecs, sizeof(info->monspecs));
+ info->fix = atmel_lcdfb_fix;
+
+ /* Enable LCDC Clocks */
+ if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) {
+ sinfo->bus_clk = clk_get(dev, "hck1");
+ if (IS_ERR(sinfo->bus_clk)) {
+ ret = PTR_ERR(sinfo->bus_clk);
+ goto free_info;
+ }
+ }
+ sinfo->lcdc_clk = clk_get(dev, "lcdc_clk");
+ if (IS_ERR(sinfo->lcdc_clk)) {
+ ret = PTR_ERR(sinfo->lcdc_clk);
+ goto put_bus_clk;
+ }
+ atmel_lcdfb_start_clock(sinfo);
+
+ ret = fb_find_mode(&info->var, info, NULL, info->monspecs.modedb,
+ info->monspecs.modedb_len, info->monspecs.modedb,
+ sinfo->default_bpp);
+ if (!ret) {
+ dev_err(dev, "no suitable video mode found\n");
+ goto stop_clk;
+ }
+
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!regs) {
+ dev_err(dev, "resources unusable\n");
+ ret = -ENXIO;
+ goto stop_clk;
+ }
+
+ sinfo->irq_base = platform_get_irq(pdev, 0);
+ if (sinfo->irq_base < 0) {
+ dev_err(dev, "unable to get irq\n");
+ ret = sinfo->irq_base;
+ goto stop_clk;
+ }
+
+ /* Initialize video memory */
+ map = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (map) {
+ /* use a pre-allocated memory buffer */
+ info->fix.smem_start = map->start;
+ info->fix.smem_len = map->end - map->start + 1;
+ if (!request_mem_region(info->fix.smem_start,
+ info->fix.smem_len, pdev->name)) {
+ ret = -EBUSY;
+ goto stop_clk;
+ }
+
+ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+ if (!info->screen_base)
+ goto release_intmem;
+ } else {
+ /* alocate memory buffer */
+ ret = atmel_lcdfb_alloc_video_memory(sinfo);
+ if (ret < 0) {
+ dev_err(dev, "cannot allocate framebuffer: %d\n", ret);
+ goto stop_clk;
+ }
+ }
+
+ /* LCDC registers */
+ info->fix.mmio_start = regs->start;
+ info->fix.mmio_len = regs->end - regs->start + 1;
+
+ if (!request_mem_region(info->fix.mmio_start,
+ info->fix.mmio_len, pdev->name)) {
+ ret = -EBUSY;
+ goto free_fb;
+ }
+
+ sinfo->mmio = ioremap(info->fix.mmio_start, info->fix.mmio_len);
+ if (!sinfo->mmio) {
+ dev_err(dev, "cannot map LCDC registers\n");
+ goto release_mem;
+ }
+
+ /* interrupt */
+ ret = request_irq(sinfo->irq_base, atmel_lcdfb_interrupt, 0, pdev->name, info);
+ if (ret) {
+ dev_err(dev, "request_irq failed: %d\n", ret);
+ goto unmap_mmio;
+ }
+
+ ret = atmel_lcdfb_init_fbinfo(sinfo);
+ if (ret < 0) {
+ dev_err(dev, "init fbinfo failed: %d\n", ret);
+ goto unregister_irqs;
+ }
+
+ /*
+ * This makes sure that our colour bitfield
+ * descriptors are correctly initialised.
+ */
+ atmel_lcdfb_check_var(&info->var, info);
+
+ ret = fb_set_var(info, &info->var);
+ if (ret) {
+ dev_warn(dev, "unable to set display parameters\n");
+ goto free_cmap;
+ }
+
+ dev_set_drvdata(dev, info);
+
+ /*
+ * Tell the world that we're ready to go
+ */
+ ret = register_framebuffer(info);
+ if (ret < 0) {
+ dev_err(dev, "failed to register framebuffer device: %d\n", ret);
+ goto free_cmap;
+ }
+
+ /* Power up the LCDC screen */
+ if (sinfo->atmel_lcdfb_power_control)
+ sinfo->atmel_lcdfb_power_control(1);
+
+ dev_info(dev, "fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %lu\n",
+ info->node, info->fix.mmio_start, sinfo->mmio, sinfo->irq_base);
+
+ return 0;
+
+
+free_cmap:
+ fb_dealloc_cmap(&info->cmap);
+unregister_irqs:
+ free_irq(sinfo->irq_base, info);
+unmap_mmio:
+ iounmap(sinfo->mmio);
+release_mem:
+ release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+free_fb:
+ if (map)
+ iounmap(info->screen_base);
+ else
+ atmel_lcdfb_free_video_memory(sinfo);
+
+release_intmem:
+ if (map)
+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
+stop_clk:
+ atmel_lcdfb_stop_clock(sinfo);
+ clk_put(sinfo->lcdc_clk);
+put_bus_clk:
+ if (sinfo->bus_clk)
+ clk_put(sinfo->bus_clk);
+free_info:
+ framebuffer_release(info);
+out:
+ dev_dbg(dev, "%s FAILED\n", __func__);
+ return ret;
+}
+
+static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct atmel_lcdfb_info *sinfo = info->par;
+
+ if (!sinfo)
+ return 0;
+
+ if (sinfo->atmel_lcdfb_power_control)
+ sinfo->atmel_lcdfb_power_control(0);
+ unregister_framebuffer(info);
+ atmel_lcdfb_stop_clock(sinfo);
+ clk_put(sinfo->lcdc_clk);
+ if (sinfo->bus_clk)
+ clk_put(sinfo->bus_clk);
+ fb_dealloc_cmap(&info->cmap);
+ free_irq(sinfo->irq_base, info);
+ iounmap(sinfo->mmio);
+ release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+ if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) {
+ iounmap(info->screen_base);
+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
+ } else {
+ atmel_lcdfb_free_video_memory(sinfo);
+ }
+
+ dev_set_drvdata(dev, NULL);
+ framebuffer_release(info);
+
+ return 0;
+}
+
+static struct platform_driver atmel_lcdfb_driver = {
+ .remove = __exit_p(atmel_lcdfb_remove),
+ .driver = {
+ .name = "atmel_lcdfb",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init atmel_lcdfb_init(void)
+{
+ return platform_driver_probe(&atmel_lcdfb_driver, atmel_lcdfb_probe);
+}
+
+static void __exit atmel_lcdfb_exit(void)
+{
+ platform_driver_unregister(&atmel_lcdfb_driver);
+}
+
+module_init(atmel_lcdfb_init);
+module_exit(atmel_lcdfb_exit);
+
+MODULE_DESCRIPTION("AT91/AT32 LCD Controller framebuffer driver");
+MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@rfo.atmel.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index aa3935df852..63b85bf81a6 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -19,13 +19,6 @@ config VGA_CONSOLE
Say Y.
-# if [ "$CONFIG_PCI" = "y" -a "$CONFIG_VGA_CONSOLE" = "y" ]; then
-# bool ' Allow VGA on any bus?' CONFIG_VGA_HOSE
-# if [ "$CONFIG_VGA_HOSE" = "y" ]; then
-# define_bool CONFIG_DUMMY_CONSOLE y
-# fi
-# fi
-
config VGACON_SOFT_SCROLLBACK
bool "Enable Scrollback Buffer in System RAM"
depends on VGA_CONSOLE
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index c627955aa12..aff11bbf59a 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -149,7 +149,9 @@ static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk,
pll = NV_RD32(par->PMC, 0x4024);
M = pll & 0xFF;
N = (pll >> 8) & 0xFF;
- if (((par->Chipset & 0xfff0) == 0x0290) || ((par->Chipset & 0xfff0) == 0x0390) || ((par->Chipset & 0xfff0) == 0x02E0)) {
+ if (((par->Chipset & 0xfff0) == 0x0290) ||
+ ((par->Chipset & 0xfff0) == 0x0390) ||
+ ((par->Chipset & 0xfff0) == 0x02E0)) {
MB = 1;
NB = 1;
} else {
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index f85edf084da..41f63658572 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -37,7 +37,6 @@
#include "nv_proto.h"
#include "nv_dma.h"
-#undef CONFIG_FB_NVIDIA_DEBUG
#ifdef CONFIG_FB_NVIDIA_DEBUG
#define NVTRACE printk
#else
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 1ac5264bb2c..ab5e66890e4 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -204,17 +204,6 @@ static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
}
#endif
-static void wait_pm2(struct pm2fb_par* par) {
-
- WAIT_FIFO(par, 1);
- pm2_WR(par, PM2R_SYNC, 0);
- mb();
- do {
- while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0);
- rmb();
- } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
-}
-
/*
* partial products for the supported horizontal resolutions.
*/
@@ -1050,13 +1039,30 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info)
return 0;
}
+static int pm2fb_sync(struct fb_info *info)
+{
+ struct pm2fb_par *par = info->par;
+
+ WAIT_FIFO(par, 1);
+ pm2_WR(par, PM2R_SYNC, 0);
+ mb();
+ do {
+ while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0)
+ udelay(10);
+ rmb();
+ } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
+
+ return 0;
+}
+
/*
* block operation. copy=0: rectangle fill, copy=1: rectangle copy.
*/
-static void pm2fb_block_op(struct pm2fb_par* par, int copy,
+static void pm2fb_block_op(struct fb_info* info, int copy,
s32 xsrc, s32 ysrc,
s32 x, s32 y, s32 w, s32 h,
u32 color) {
+ struct pm2fb_par *par = info->par;
if (!w || !h)
return;
@@ -1076,13 +1082,11 @@ static void pm2fb_block_op(struct pm2fb_par* par, int copy,
(x<xsrc ? PM2F_INCREASE_X : 0) |
(y<ysrc ? PM2F_INCREASE_Y : 0) |
(copy ? 0 : PM2F_RENDER_FASTFILL));
- wait_pm2(par);
}
static void pm2fb_fillrect (struct fb_info *info,
const struct fb_fillrect *region)
{
- struct pm2fb_par *par = info->par;
struct fb_fillrect modded;
int vxres, vyres;
u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
@@ -1116,7 +1120,7 @@ static void pm2fb_fillrect (struct fb_info *info,
color |= color << 16;
if(info->var.bits_per_pixel != 24)
- pm2fb_block_op(par, 0, 0, 0,
+ pm2fb_block_op(info, 0, 0, 0,
modded.dx, modded.dy,
modded.width, modded.height, color);
else
@@ -1126,7 +1130,6 @@ static void pm2fb_fillrect (struct fb_info *info,
static void pm2fb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
- struct pm2fb_par *par = info->par;
struct fb_copyarea modded;
u32 vxres, vyres;
@@ -1156,7 +1159,7 @@ static void pm2fb_copyarea(struct fb_info *info,
if(modded.dy + modded.height > vyres)
modded.height = vyres - modded.dy;
- pm2fb_block_op(par, 1, modded.sx, modded.sy,
+ pm2fb_block_op(info, 1, modded.sx, modded.sy,
modded.dx, modded.dy,
modded.width, modded.height, 0);
}
@@ -1177,6 +1180,7 @@ static struct fb_ops pm2fb_ops = {
.fb_fillrect = pm2fb_fillrect,
.fb_copyarea = pm2fb_copyarea,
.fb_imageblit = cfb_imageblit,
+ .fb_sync = pm2fb_sync,
};
/*
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index bd787e80177..c77a1a1fd46 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -1,55 +1,25 @@
/*
* linux/drivers/video/pm3fb.c -- 3DLabs Permedia3 frame buffer device
- *
- * Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr>
+ *
+ * Copyright (C) 2001 Romain Dolbeau <romain@dolbeau.org>.
+ *
+ * Ported to 2.6 kernel on 1 May 2007 by Krzysztof Helt <krzysztof.h1@wp.pl>
+ * based on pm2fb.c
+ *
* Based on code written by:
- * Sven Luther, <luther@dpt-info.u-strasbg.fr>
- * Alan Hourihane, <alanh@fairlite.demon.co.uk>
- * Russell King, <rmk@arm.linux.org.uk>
+ * Sven Luther, <luther@dpt-info.u-strasbg.fr>
+ * Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Russell King, <rmk@arm.linux.org.uk>
* Based on linux/drivers/video/skeletonfb.c:
* Copyright (C) 1997 Geert Uytterhoeven
* Based on linux/driver/video/pm2fb.c:
- * Copyright (C) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
- * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
+ * Copyright (C) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
+ * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
*
* 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.
*
- * $Header: /cvsroot/linux/drivers/video/pm3fb.c,v 1.1 2002/02/25 19:11:06 marcelo Exp $
- *
- * CHANGELOG:
- * Mon Feb 11 10:35:48 MET 2002, v 1.4.11B: Cosmetic update.
- * Wed Jan 23 14:16:59 MET 2002, v 1.4.11: Preliminary 2.5.x support, patch for 2.5.2.
- * Wed Nov 28 11:08:29 MET 2001, v 1.4.10: potential bug fix for SDRAM-based board, patch for 2.4.16.
- * Thu Sep 20 10:24:42 MET DST 2001, v 1.4.9: sync bug fix, preliminary flatpanel support, better timings.
- * Tue Aug 28 10:13:01 MET DST 2001, v 1.4.8: memory timings check, minor bug fixes.
- * Wed Jul 18 19:06:14 CEST 2001, v 1.4.7: Mode fix (800x600-100, 1024x768-100 changed), using HW panning + accel bug fix.
- * Mon Jun 25 10:33:56 MET DST 2001, v 1.4.6: Depth 12 fix, chip reset ioctl, moved memory erase ioctl to DEBUG.
- * Wed Jun 20 11:13:08 MET DST 2001, v 1.4.5: Fixed missing blinking cursor in 8bpp, code cleaning, memory erase IOCTL.
- * Mon Jun 18 16:00:27 CEST 2001, v 1.4.4: Depth 12 (RGBA 4444) support, code cleaning.
- * Fri Jun 15 13:53:01 CEST 2001, v 1.4.3: Removed warnings, depth 15 support, add 'depth' option.
- * Thu Jun 14 10:13:52 MET DST 2001, v 1.4.2: Fixed depth switching bug, preliminary 15bpp (RGB5551) support.
- * Thu Apr 12 11:16:45 MET DST 2001, v 1.4.1B: Doc updates.
- * Fri Apr 6 11:12:53 MET DST 2001, v 1.4.1: Configure.help, minor cleanup
- * Thu Mar 29 10:56:50 MET DST 2001, v 1.4.0: Module & module options support (note: linux patch changed, 2.2.19 added).
- * Thu Mar 15 15:30:31 MET 2001, v 1.3.2: Fixed mirroring bug on little-endian.
- * Wed Mar 14 21:25:54 CET 2001, v 1.3.1: Fixed bug in BlockMove (_bmov).
- * Tue Mar 13 10:53:19 MET 2001, v 1.3.0: Character drawing hardware support (in all width between 1 and 16), fixes.
- * Thu Mar 8 10:20:16 MET 2001, v 1.2.2: Better J2000 support, "font:" option.
- * Tue Mar 6 21:25:04 CET 2001, v 1.2.1: Better acceleration support.
- * Mon Mar 5 21:54:17 CET 2001, v 1.2.0: Partial acceleration support (clear & bmove)
- * Mon Mar 5 12:52:15 CET 2001, v 1.1.3: Big pan_display fix.
- * Sun Mar 4 22:21:50 CET 2001, v 1.1.2: (numerous) bug fixes.
- * Fri Mar 2 15:54:07 CET 2001, v 1.1.1: Might have Appian J2000 support, resource mangement in 2.4
- * Wed Feb 28 18:21:35 CET 2001, v 1.1.0: Might have multiple boards support (added, but not yest tested)
- * Tue Feb 27 17:31:12 CET 2001, v 1.0.6: fixes boot-time mode select, add more default mode
- * Tue Feb 27 14:01:36 CET 2001, v 1.0.5: fixes (1.0.4 was broken for 2.2), cleaning up
- * Mon Feb 26 23:17:36 CET 2001, v 1.0.4: preliminary 2.4.x support, dropped (useless on pm3) partial product, more OF fix
- * Mon Feb 26 20:59:05 CET 2001, v 1.0.3: No more shadow register (and wasted memory), endianess fix, use OF-preset resolution by default
- * Wed Feb 21 22:09:30 CET 2001, v 1.0.2: Code cleaning for future multiboard support, better OF support, bugs fix
- * Wed Feb 21 19:58:56 CET 2001, v 1.0.1: OpenFirmware support, fixed memory detection, better debug support, code cleaning
- * Wed Feb 21 14:47:06 CET 2001, v 1.0.0: First working version
*/
#include <linux/module.h>
@@ -58,856 +28,155 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include <linux/delay.h>
-#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/ctype.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb2.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
-#include <video/pm3fb.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <video/pm3fb.h>
-#ifdef CONFIG_FB_OF
-#include <asm/prom.h>
+#if !defined(CONFIG_PCI)
+#error "Only generic PCI cards supported."
#endif
-/* ************************************* */
-/* ***** The various "global" data ***** */
-/* ************************************* */
-
-/* those will need a rework for multiple board support */
-/* Driver name */
-static const char permedia3_name[16] = "Permedia3";
-
-/* the fb_par struct, mandatory */
-struct pm3fb_par {
- u32 pixclock; /* pixclock in KHz */
-
- u32 width; /* width of virtual screen */
- u32 height; /* height of virtual screen */
-
- u32 hsstart; /* horiz. sync start */
- u32 hsend; /* horiz. sync end */
- u32 hbend; /* horiz. blank end (also gate end) */
- u32 htotal; /* total width (w/ sync & blank) */
-
- u32 vsstart; /* vert. sync start */
- u32 vsend; /* vert. sync end */
- u32 vbend; /* vert. blank end */
- u32 vtotal; /* total height (w/ sync & blank) */
-
- u32 stride; /* screen stride */
- u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */
- /* NOTE : unlike other pm3 stuff above, stored *after* shiftbpp. don't ask */
- u32 depth; /* screen depth (8, 12, 15, 16 or 32) */
- u32 video; /* video control (hsync,vsync) */
-};
-
-/* memory timings */
-struct pm3fb_timings
-{
- unsigned long caps;
- unsigned long timings;
- unsigned long control;
- unsigned long refresh;
- unsigned long powerdown;
-};
-typedef enum pm3fb_timing_result { pm3fb_timing_ok, pm3fb_timing_problem, pm3fb_timing_retry } pm3fb_timing_result;
-#define PM3FB_UNKNOWN_TIMING_VALUE ((unsigned long)-1)
-#define PM3FB_UNKNOWN_TIMINGS { PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE }
-
-/* the fb_info struct, mandatory */
-struct pm3fb_info {
- struct fb_info_gen gen;
- unsigned long board_num; /* internal board number */
- unsigned long use_current;
- struct pm3fb_par *current_par;
- struct pci_dev *dev; /* PCI device */
- unsigned long board_type; /* index in the cardbase */
- unsigned char *fb_base; /* framebuffer memory base */
- u32 fb_size; /* framebuffer memory size */
- unsigned char *p_fb; /* physical address of frame buffer */
- unsigned char *v_fb; /* virtual address of frame buffer */
- unsigned char *pIOBase; /* physical address of registers region, must be rg_base or rg_base+PM2_REGS_SIZE depending on the host endianness */
- unsigned char *vIOBase; /* address of registers after ioremap() */
- struct {
- u8 transp;
- u8 red;
- u8 green;
- u8 blue;
- } palette[256];
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cmap12[16]; /* RGBA 4444 */
- u16 cmap15[16]; /* RGBA 5551 */
- u16 cmap16[16]; /* RGBA 5650 */
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cmap32[16];
+#undef PM3FB_MASTER_DEBUG
+#ifdef PM3FB_MASTER_DEBUG
+#define DPRINTK(a,b...) printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b)
+#else
+#define DPRINTK(a,b...)
#endif
- } cmap;
- struct pm3fb_timings memt;
-};
-/* regular resolution database*/
-static struct {
- char name[16];
- struct pm3fb_par user_mode;
-} mode_base[] __initdata = {
- {
- "default-800x600", {
- 49500, 800, 600, 16, 96, 256, 1056, 1, 4, 25, 625,
- 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}}, {
- "1024x768-74", {
- 78752, 1024, 768, 32, 128, 304, 1328, 1, 4, 38,
- 806, 1024, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}}, {
- "1024x768-74-32", {
- 78752, 1024, 768, 32, 128, 304, 1328, 1, 4, 38,
- 806, 1024, 0, 32,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_32BIT}},
-/* Generated mode : "1600x1024", for the SGI 1600SW flat panel*/
- {
- "SGI1600SW", {
- 108000, 1600, 1024, 16, 56, 104, 1704, 3, 6, 32,
- 1056, 1600, 0, 8,
- PM3VideoControl_ENABLE|
- PM3VideoControl_HSYNC_ACTIVE_LOW|PM3VideoControl_VSYNC_ACTIVE_LOW|
- PM3VideoControl_PIXELSIZE_32BIT}},
-/* ##### auto-generated mode, by fbtimings2pm3 */
-/* Generated mode : "640x480-60" */
- {
- "640x480-60", {
- 25174, 640, 480, 16, 112, 160, 800, 10, 12, 45,
- 525, 640, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "640x480-72" */
- {
- "640x480-72", {
- 31199, 640, 480, 24, 64, 192, 832, 9, 12, 40, 520,
- 640, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "640x480-75" */
- {
- "640x480-75", {
- 31499, 640, 480, 16, 80, 200, 840, 1, 4, 20, 500,
- 640, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "640x480-90" */
- {
- "640x480-90", {
- 39909, 640, 480, 32, 72, 192, 832, 25, 39, 53, 533,
- 640, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "640x480-100" */
- {
- "640x480-100", {
- 44899, 640, 480, 32, 160, 208, 848, 22, 34, 51,
- 531, 640, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "800x600-48-lace" */
-/* INTERLACED NOT SUPPORTED
- {"800x600-48-lace", {35999, 800, 600, 80, 208, 264, 1064, 11, 23, 102, 702, 800, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}},
- INTERLACED NOT SUPPORTED */
-/* Generated mode : "800x600-56" */
- {
- "800x600-56", {
- 35999, 800, 600, 24, 96, 224, 1024, 1, 3, 25, 625,
- 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "800x600-60" */
- {
- "800x600-60", {
- 40000, 800, 600, 40, 168, 256, 1056, 1, 5, 28, 628,
- 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "800x600-70" */
- {
- "800x600-70", {
- 44899, 800, 600, 24, 168, 208, 1008, 9, 21, 36,
- 636, 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "800x600-72" */
- {
- "800x600-72", {
- 50000, 800, 600, 56, 176, 240, 1040, 37, 43, 66,
- 666, 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "800x600-75" */
- {
- "800x600-75", {
- 49497, 800, 600, 16, 96, 256, 1056, 1, 4, 25, 625,
- 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "800x600-90" */
- {
- "800x600-90", {
- 56637, 800, 600, 8, 72, 192, 992, 8, 19, 35, 635,
- 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "800x600-100", from /etc/fb.modes */
-/* DISABLED, hsstart == 0
- {
- "800x600-100", {
- 67499, 800, 600, 0, 64, 280, 1080, 7, 11, 25, 625,
- 800, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-*/
-/* Generated mode : "800x600-100", from ??? */
- {
- "800x600-100", {
- 69650, 800, 600, 64, 128, 288, 1088, 4, 10, 40, 640, 800, 0, 8,
- PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_LOW|
- PM3VideoControl_VSYNC_ACTIVE_LOW|PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1024x768-43-lace" */
-/* INTERLACED NOT SUPPORTED
- {"1024x768-43-lace", {44899, 1024, 768, 8, 184, 240, 1264, 1, 9, 49, 817, 1024, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}},
- INTERLACED NOT SUPPORTED */
-/* Generated mode : "1024x768-60" */
- {
- "1024x768-60", {
- 64998, 1024, 768, 24, 160, 320, 1344, 3, 9, 38,
- 806, 1024, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1024x768-70" */
- {
- "1024x768-70", {
- 74996, 1024, 768, 24, 160, 304, 1328, 3, 9, 38,
- 806, 1024, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1024x768-72" */
- {
- "1024x768-72", {
- 74996, 10224, 768, 24, 160, 264, 10488, 3, 9, 38,
- 806, 10224, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1024x768-75" */
- {
- "1024x768-75", {
- 78746, 1024, 768, 16, 112, 288, 1312, 1, 4, 32,
- 800, 1024, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1024x768-90" */
- {
- "1024x768-90", {
- 100000, 1024, 768, 0, 96, 288, 1312, 21, 36, 77,
- 845, 1024, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1024x768-100", from /etc/fb.modes */
-/* DISABLED, vsstart == 0
- {
- "1024x768-100", {
- 109998, 1024, 768, 0, 88, 368, 1392, 0, 8, 24, 792,
- 1024, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-*/
-/* Generated mode : "1024x768-100", from ??? */
- {
- "1024x768-100", {
- 115500, 1024, 768, 32, 224, 416, 1440, 3, 13, 34, 802, 1024, 0, 8,
- PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_LOW|
- PM3VideoControl_VSYNC_ACTIVE_LOW|PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1152x864-43-lace" */
-/* INTERLACED NOT SUPPORTED
- {"1152x864-43-lace", {64998, 1152, 864, 72, 200, 264, 1416, 78, 87, 191, 1055, 1152, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}},
- INTERLACED NOT SUPPORTED */
-/* Generated mode : "1152x864-47-lace" */
-/* INTERLACED NOT SUPPORTED
- {"1152x864-47-lace", {64998, 1152, 864, 88, 216, 296, 1448, 30, 39, 83, 947, 1152, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}},
- INTERLACED NOT SUPPORTED */
-/* Generated mode : "1152x864-60" */
- {
- "1152x864-60", {
- 80000, 1152, 864, 64, 176, 304, 1456, 6, 11, 52,
- 916, 1152, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1152x864-70" */
- {
- "1152x864-70", {
- 100000, 1152, 864, 40, 192, 360, 1512, 13, 24, 81,
- 945, 1152, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1152x864-75" */
- {
- "1152x864-75", {
- 109998, 1152, 864, 24, 168, 312, 1464, 45, 53, 138,
- 1002, 1152, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1152x864-80" */
- {
- "1152x864-80", {
- 109998, 1152, 864, 16, 128, 288, 1440, 30, 37, 94,
- 958, 1152, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1280x1024-43-lace" */
-/* INTERLACED NOT SUPPORTED
- {"1280x1024-43-lace", {80000, 1024, 1024, 80, 160, 320, 1344, 50, 60, 125, 1149, 1024, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}},
- INTERLACED NOT SUPPORTED */
-/* Generated mode : "1280x1024-47-lace" */
-/* INTERLACED NOT SUPPORTED
- {"1280x1024-47-lace", {80000, 1280, 1024, 80, 160, 320, 1600, 1, 11, 29, 1053, 1280, 0, 8, PM3VideoControl_ENABLE|PM3VideoControl_HSYNC_ACTIVE_HIGH|PM3VideoControl_VSYNC_ACTIVE_HIGH|PM3VideoControl_PIXELSIZE_8BIT}},
- INTERLACED NOT SUPPORTED */
-/* Generated mode : "1280x1024-60" */
- {
- "1280x1024-60", {
- 107991, 1280, 1024, 48, 160, 408, 1688, 1, 4, 42,
- 1066, 1280, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1280x1024-70" */
- {
- "1280x1024-70", {
- 125992, 1280, 1024, 80, 192, 408, 1688, 1, 6, 42,
- 1066, 1280, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1280x1024-74" */
- {
- "1280x1024-74", {
- 134989, 1280, 1024, 32, 176, 432, 1712, 0, 30, 40,
- 1064, 1280, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1280x1024-75" */
- {
- "1280x1024-75", {
- 134989, 1280, 1024, 16, 160, 408, 1688, 1, 4, 42,
- 1066, 1280, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_HIGH
- |
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1600x1200-60" */
- {
- "1600x1200-60", {
- 155981, 1600, 1200, 32, 192, 448, 2048, 10, 18, 70,
- 1270, 1600, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1600x1200-66" */
- {
- "1600x1200-66", {
- 171998, 1600, 1200, 40, 176, 480, 2080, 3, 6, 53,
- 1253, 1600, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* Generated mode : "1600x1200-76" */
- {
- "1600x1200-76", {
- 197980, 1600, 1200, 40, 176, 480, 2080, 3, 8, 50,
- 1250, 1600, 0, 8,
- PM3VideoControl_ENABLE |
- PM3VideoControl_HSYNC_ACTIVE_LOW
- |
- PM3VideoControl_VSYNC_ACTIVE_LOW
- | PM3VideoControl_PIXELSIZE_8BIT}},
-/* ##### end of auto-generated mode */
- {
- "\0",}
-};
-
-/* more mandatory stuff (see skeletonfb.c + framebuffer driver HOWTO */
-static struct pm3fb_info fb_info[PM3_MAX_BOARD];
-static struct pm3fb_par current_par[PM3_MAX_BOARD];
-static int current_par_valid[PM3_MAX_BOARD];
-/* to allow explicit filtering of board */
-short bus[PM3_MAX_BOARD];
-short slot[PM3_MAX_BOARD];
-short func[PM3_MAX_BOARD];
-short disable[PM3_MAX_BOARD];
-short noaccel[PM3_MAX_BOARD];
-char fontn[PM3_MAX_BOARD][PM3_FONTNAME_SIZE];
-short depth[PM3_MAX_BOARD];
-short flatpanel[PM3_MAX_BOARD];
-static struct display disp[PM3_MAX_BOARD];
-static char g_options[PM3_OPTIONS_SIZE] __initdata = "pm3fb,dummy";
-short printtimings = 0;
-short forcesize[PM3_MAX_BOARD];
-
-/* ********************* */
-/* ***** prototype ***** */
-/* ********************* */
-/* card-specific */
-static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info);
-/* permedia3-specific */
-static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info);
-static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info);
-static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info);
-static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info,
- unsigned long r);
-static unsigned long pm3fb_CalculateClock(struct pm3fb_info *l_fb_info, unsigned long reqclock, /* In kHz units */
- unsigned long refclock, /* In kHz units */
- unsigned char *prescale, /* ClkPreScale */
- unsigned char *feedback, /* ClkFeedBackScale */
- unsigned char *postscale
- /* ClkPostScale */ );
-static void pm3fb_clear_memory(struct pm3fb_info *l_fb_info, u32 cc);
-static void pm3fb_clear_colormap(struct pm3fb_info *l_fb_info, unsigned char r, unsigned char g, unsigned char b);
-static void pm3fb_common_init(struct pm3fb_info *l_fb_info);
-static int pm3fb_Shiftbpp(struct pm3fb_info *l_fb_info,
- unsigned long depth, int v);
-static int pm3fb_Unshiftbpp(struct pm3fb_info *l_fb_info,
- unsigned long depth, int v);
-static void pm3fb_mapIO(struct pm3fb_info *l_fb_info);
-static void pm3fb_unmapIO(struct pm3fb_info *l_fb_info);
-#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
-static void pm3fb_show_cur_mode(struct pm3fb_info *l_fb_info);
-#endif
-static void pm3fb_show_cur_timing(struct pm3fb_info *l_fb_info);
-static void pm3fb_write_mode(struct pm3fb_info *l_fb_info);
-static void pm3fb_read_mode(struct pm3fb_info *l_fb_info,
- struct pm3fb_par *curpar);
-static unsigned long pm3fb_size_memory(struct pm3fb_info *l_fb_info);
-/* accelerated permedia3-specific */
-#ifdef PM3FB_USE_ACCEL
-static void pm3fb_wait_pm3(struct pm3fb_info *l_fb_info);
-static void pm3fb_init_engine(struct pm3fb_info *l_fb_info);
-#ifdef FBCON_HAS_CFB32
-static void pm3fb_cfb32_clear(struct vc_data *conp,
- struct display *p,
- int sy, int sx, int height, int width);
-static void pm3fb_cfb32_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only);
-#endif /* FBCON_HAS_CFB32 */
-#ifdef FBCON_HAS_CFB16
-static void pm3fb_cfb16_clear(struct vc_data *conp,
- struct display *p,
- int sy, int sx, int height, int width);
-static void pm3fb_cfb16_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only);
-#endif /* FBCON_HAS_CFB16 */
-#ifdef FBCON_HAS_CFB8
-static void pm3fb_cfb8_clear(struct vc_data *conp,
- struct display *p,
- int sy, int sx, int height, int width);
-static void pm3fb_cfb8_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only);
-#endif /* FBCON_HAS_CFB8 */
-#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
-static void pm3fb_cfbX_bmove(struct display *p,
- int sy, int sx,
- int dy, int dx, int height, int width);
-static void pm3fb_cfbX_putc(struct vc_data *conp, struct display *p,
- int c, int yy, int xx);
-static void pm3fb_cfbX_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy,
- int xx);
-static void pm3fb_cfbX_revc(struct display *p, int xx, int yy);
-#endif /* FBCON_HAS_CFB8 || FBCON_HAS_CFB16 || FBCON_HAS_CFB32 */
-#endif /* PM3FB_USE_ACCEL */
-/* pre-init */
-static void pm3fb_mode_setup(char *mode, unsigned long board_num);
-static void pm3fb_pciid_setup(char *pciid, unsigned long board_num);
-static char *pm3fb_boardnum_setup(char *options, unsigned long *bn);
-static void pm3fb_real_setup(char *options);
-/* fbdev */
-static int pm3fb_encode_fix(struct fb_fix_screeninfo *fix,
- const void *par, struct fb_info_gen *info);
-static int pm3fb_decode_var(const struct fb_var_screeninfo *var,
- void *par, struct fb_info_gen *info);
-static void pm3fb_encode_depth(struct fb_var_screeninfo *var, long d);
-static int pm3fb_encode_var(struct fb_var_screeninfo *var,
- const void *par, struct fb_info_gen *info);
-static void pm3fb_get_par(void *par, struct fb_info_gen *info);
-static void pm3fb_set_par(const void *par, struct fb_info_gen *info);
-static void pm3fb_set_color(struct pm3fb_info *l_fb_info,
- unsigned char regno, unsigned char r,
- unsigned char g, unsigned char b);
-static int pm3fb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info);
-static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info);
-static int pm3fb_blank(int blank_mode, struct fb_info_gen *info);
-static void pm3fb_set_disp(const void *par, struct display *disp,
- struct fb_info_gen *info);
-static void pm3fb_detect(void);
-static int pm3fb_pan_display(const struct fb_var_screeninfo *var,
- struct fb_info_gen *info);
-static int pm3fb_ioctl(struct fb_info *info, u_int cmd, u_long arg);
-
-
-/* the struct that hold them together */
-struct fbgen_hwswitch pm3fb_switch = {
- pm3fb_detect, pm3fb_encode_fix, pm3fb_decode_var, pm3fb_encode_var,
- pm3fb_get_par, pm3fb_set_par, pm3fb_getcolreg,
- pm3fb_pan_display, pm3fb_blank, pm3fb_set_disp
-};
+/*
+ * Driver data
+ */
+static char *mode_option __devinitdata;
-static struct fb_ops pm3fb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = fbgen_get_fix,
- .fb_get_var = fbgen_get_var,
- .fb_set_var = fbgen_set_var,
- .fb_get_cmap = fbgen_get_cmap,
- .fb_set_cmap = fbgen_set_cmap,
- .fb_setcolreg = pm3fb_setcolreg,
- .fb_pan_display =fbgen_pan_display,
- .fb_blank = fbgen_blank,
- .fb_ioctl = pm3fb_ioctl,
-};
+/*
+ * If your driver supports multiple boards, you should make the
+ * below data types arrays, or allocate them dynamically (using kmalloc()).
+ */
-#ifdef PM3FB_USE_ACCEL
-#ifdef FBCON_HAS_CFB32
-static struct display_switch pm3fb_cfb32 = {
- fbcon_cfb32_setup, pm3fb_cfbX_bmove, pm3fb_cfb32_clear,
- pm3fb_cfbX_putc, pm3fb_cfbX_putcs, pm3fb_cfbX_revc,
- NULL /* cursor() */ , NULL /* set_font() */ ,
- pm3fb_cfb32_clear_margins,
- FONTWIDTHRANGE(1, 16) /* true only if accelerated... */
-};
-#endif /* FBCON_HAS_CFB32 */
-#ifdef FBCON_HAS_CFB16
-static struct display_switch pm3fb_cfb16 = {
- fbcon_cfb16_setup, pm3fb_cfbX_bmove, pm3fb_cfb16_clear,
- pm3fb_cfbX_putc, pm3fb_cfbX_putcs, pm3fb_cfbX_revc,
- NULL /* cursor() */ , NULL /* set_font() */ ,
- pm3fb_cfb16_clear_margins,
- FONTWIDTHRANGE(1, 16) /* true only if accelerated... */
-};
-#endif /* FBCON_HAS_CFB16 */
-#ifdef FBCON_HAS_CFB8
-static struct display_switch pm3fb_cfb8 = {
- fbcon_cfb8_setup, pm3fb_cfbX_bmove, pm3fb_cfb8_clear,
- pm3fb_cfbX_putc, pm3fb_cfbX_putcs, pm3fb_cfbX_revc,
- NULL /* cursor() */ , NULL /* set_font() */ ,
- pm3fb_cfb8_clear_margins,
- FONTWIDTHRANGE(1, 16) /* true only if accelerated... */
-};
-#endif /* FBCON_HAS_CFB8 */
-#endif /* PM3FB_USE_ACCEL */
-
-/* ****************************** */
-/* ***** card-specific data ***** */
-/* ****************************** */
-struct pm3fb_card_timings {
- unsigned long memsize; /* 0 for last value (i.e. default) */
- struct pm3fb_timings memt;
+/*
+ * This structure defines the hardware state of the graphics card. Normally
+ * you place this in a header file in linux/include/video. This file usually
+ * also includes register information. That allows other driver subsystems
+ * and userland applications the ability to use the same header file to
+ * avoid duplicate work and easy porting of software.
+ */
+struct pm3_par {
+ unsigned char __iomem *v_regs;/* virtual address of p_regs */
+ u32 video; /* video flags before blanking */
+ u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */
+ u32 palette[16];
};
-static struct pm3fb_card_timings t_FormacProFormance3[] = {
- { 16, { 0x02e311b8, 0x06100205, 0x08000002, 0x00000079, 0x00000000} },
- { 0, { 0x02e311b8, 0x06100205, 0x08000002, 0x00000079, 0x00000000} } /* from 16 MB PF3 */
+/*
+ * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
+ * if we don't use modedb. If we do use modedb see pm3fb_init how to use it
+ * to get a fb_var_screeninfo. Otherwise define a default var as well.
+ */
+static struct fb_fix_screeninfo pm3fb_fix __devinitdata = {
+ .id = "Permedia3",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .xpanstep = 1,
+ .ypanstep = 1,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
};
-static struct pm3fb_card_timings t_AppianJeronimo2000[] = {
- { 32, { 0x02e311B8, 0x07424905, 0x0c000003, 0x00000061, 0x00000000} },
- { 0, { 0x02e311B8, 0x07424905, 0x0c000003, 0x00000061, 0x00000000} } /* from 32MB J2000 */
-};
+/*
+ * Utility functions
+ */
-static struct pm3fb_card_timings t_3DLabsOxygenVX1[] = {
- { 32, { 0x30e311b8, 0x08501204, 0x08000002, 0x0000006b, 0x00000000} },
- { 0, { 0x30e311b8, 0x08501204, 0x08000002, 0x0000006b, 0x00000000} } /* from 32MB VX1 */
-};
+static inline u32 PM3_READ_REG(struct pm3_par *par, s32 off)
+{
+ return fb_readl(par->v_regs + off);
+}
-static struct {
- char cardname[32]; /* recognized card name */
- u16 subvendor; /* subvendor of the card */
- u16 subdevice; /* subdevice of the card */
- u8 func; /* function of the card to which the extra init apply */
- void (*specific_setup)(struct pm3fb_info *l_fb_info); /* card/func specific setup, done before _any_ FB access */
- struct pm3fb_card_timings *c_memt; /* defauls timings for the boards */
-} cardbase[] = {
- { "Unknown Permedia3 board", 0xFFFF, 0xFFFF, 0xFF, NULL, NULL },
- { "Appian Jeronimo 2000 head 1", 0x1097, 0x3d32, 1, NULL,
- t_AppianJeronimo2000
- },
- { "Appian Jeronimo 2000 head 2", 0x1097, 0x3d32, 2, pm3fb_j2000_setup,
- t_AppianJeronimo2000
- },
- { "Formac ProFormance 3", PCI_VENDOR_ID_3DLABS, 0x000a, 0, NULL, /* Formac use 3DLabs ID ?!? */
- t_FormacProFormance3
- },
- { "3DLabs Permedia3 Create!", PCI_VENDOR_ID_3DLABS, 0x0127, 0, NULL, NULL },
- { "3DLabs Oxygen VX1 PCI", PCI_VENDOR_ID_3DLABS, 0x0121, 0, NULL,
- t_3DLabsOxygenVX1
- },
- { "3DLabs Oxygen VX1 AGP", PCI_VENDOR_ID_3DLABS, 0x0125, 0, NULL, NULL },
- { "3DLabs Oxygen VX1-16 AGP", PCI_VENDOR_ID_3DLABS, 0x0140, 0, NULL, NULL },
- { "3DLabs Oxygen VX1-1600SW PCI", PCI_VENDOR_ID_3DLABS, 0x0800, 0, NULL, NULL },
- { "\0", 0x0, 0x0, 0, NULL, NULL }
-};
+static inline void PM3_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
+{
+ fb_writel(v, par->v_regs + off);
+}
-/* ********************************** */
-/* ***** card-specific function ***** */
-/* ********************************** */
-static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info)
-{ /* the appian j2000 require more initialization of the second head */
- /* l_fb_info must point to the _second_ head of the J2000 */
-
- DTRACE;
-
- l_fb_info->memt = t_AppianJeronimo2000[0].memt; /* 32 MB, first and only j2000 ? */
-
- pm3fb_write_memory_timings(l_fb_info);
+static inline void PM3_WAIT(struct pm3_par *par, u32 n)
+{
+ while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
}
-/* *************************************** */
-/* ***** permedia3-specific function ***** */
-/* *************************************** */
-static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info)
+static inline void PM3_SLOW_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
{
- l_fb_info->memt.caps = PM3_READ_REG(PM3LocalMemCaps);
- l_fb_info->memt.timings = PM3_READ_REG(PM3LocalMemTimings);
- l_fb_info->memt.control = PM3_READ_REG(PM3LocalMemControl);
- l_fb_info->memt.refresh = PM3_READ_REG(PM3LocalMemRefresh);
- l_fb_info->memt.powerdown = PM3_READ_REG(PM3LocalMemPowerDown);
-
- if ((l_fb_info->memt.caps == PM3FB_UNKNOWN_TIMING_VALUE) ||
- (l_fb_info->memt.timings == PM3FB_UNKNOWN_TIMING_VALUE) ||
- (l_fb_info->memt.control == PM3FB_UNKNOWN_TIMING_VALUE) ||
- (l_fb_info->memt.refresh == PM3FB_UNKNOWN_TIMING_VALUE) ||
- (l_fb_info->memt.powerdown == PM3FB_UNKNOWN_TIMING_VALUE))
- {
- printk(KERN_ERR "pm3fb: invalid memory timings in permedia3 board #%ld\n", l_fb_info->board_num);
- return(pm3fb_try_memory_timings(l_fb_info));
+ if (par->v_regs) {
+ mb();
+ PM3_WAIT(par, 1);
+ wmb();
+ PM3_WRITE_REG(par, off, v);
}
- return(pm3fb_timing_ok);
}
-static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info)
+static inline void PM3_SET_INDEX(struct pm3_par *par, unsigned index)
{
- if (cardbase[l_fb_info->board_type].c_memt)
- {
- int i = 0, done = 0;
- while (!done)
- {
- if ((cardbase[l_fb_info->board_type].c_memt[i].memsize == l_fb_info->fb_size)
- || !(cardbase[l_fb_info->board_type].c_memt[i].memsize))
- { /* will use the 0-sized timings by default */
- done = 1;
- l_fb_info->memt = cardbase[l_fb_info->board_type].c_memt[i].memt;
- printk(KERN_WARNING "pm3fb: trying to use predefined memory timings for permedia3 board #%ld (%s, %ld MB)\n",
- l_fb_info->board_num,
- cardbase[l_fb_info->board_type].cardname,
- cardbase[l_fb_info->board_type].c_memt[i].memsize);
- pm3fb_write_memory_timings(l_fb_info);
- return(pm3fb_timing_retry);
- }
- i++;
- }
- } else
- return(pm3fb_timing_problem);
- return(pm3fb_timing_ok);
+ PM3_SLOW_WRITE_REG(par, PM3RD_IndexHigh, (index >> 8) & 0xff);
+ PM3_SLOW_WRITE_REG(par, PM3RD_IndexLow, index & 0xff);
+}
+
+static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
+{
+ PM3_SET_INDEX(par, r);
+ wmb();
+ PM3_WRITE_REG(par, PM3RD_IndexedData, v);
}
-static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info)
+static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno,
+ unsigned char r, unsigned char g, unsigned char b)
{
- unsigned char m, n, p;
- unsigned long clockused;
-
- PM3_SLOW_WRITE_REG(PM3LocalMemCaps, l_fb_info->memt.caps);
- PM3_SLOW_WRITE_REG(PM3LocalMemTimings, l_fb_info->memt.timings);
- PM3_SLOW_WRITE_REG(PM3LocalMemControl, l_fb_info->memt.control);
- PM3_SLOW_WRITE_REG(PM3LocalMemRefresh, l_fb_info->memt.refresh);
- PM3_SLOW_WRITE_REG(PM3LocalMemPowerDown, l_fb_info->memt.powerdown);
-
- clockused =
- pm3fb_CalculateClock(l_fb_info, 2 * 105000, PM3_REF_CLOCK, &m,
- &n, &p);
-
- PM3_WRITE_DAC_REG(PM3RD_KClkPreScale, m);
- PM3_WRITE_DAC_REG(PM3RD_KClkFeedbackScale, n);
- PM3_WRITE_DAC_REG(PM3RD_KClkPostScale, p);
- PM3_WRITE_DAC_REG(PM3RD_KClkControl,
- PM3RD_KClkControl_STATE_RUN |
- PM3RD_KClkControl_SOURCE_PLL |
- PM3RD_KClkControl_ENABLE);
- PM3_WRITE_DAC_REG(PM3RD_MClkControl,
- PM3RD_MClkControl_STATE_RUN |
- PM3RD_MClkControl_SOURCE_KCLK |
- PM3RD_MClkControl_ENABLE);
- PM3_WRITE_DAC_REG(PM3RD_SClkControl,
- PM3RD_SClkControl_STATE_RUN |
- PM3RD_SClkControl_SOURCE_PCLK |
- PM3RD_SClkControl_ENABLE);
+ PM3_SLOW_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
+ PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, r);
+ PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, g);
+ PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, b);
}
-static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info,
- unsigned long r)
+static void pm3fb_clear_colormap(struct pm3_par *par,
+ unsigned char r, unsigned char g, unsigned char b)
{
- DASSERT((l_fb_info->vIOBase != (unsigned char *) (-1)),
- "l_fb_info->vIOBase mapped in read dac reg\n");
- PM3_SET_INDEX(r);
- mb();
- return (PM3_READ_REG(PM3RD_IndexedData));
+ int i;
+
+ for (i = 0; i < 256 ; i++) /* fill color map with white */
+ pm3fb_set_color(par, i, r, g, b);
+
}
/* Calculating various clock parameter */
-static unsigned long pm3fb_CalculateClock(struct pm3fb_info *l_fb_info, unsigned long reqclock, /* In kHz units */
- unsigned long refclock, /* In kHz units */
- unsigned char *prescale, /* ClkPreScale */
- unsigned char *feedback, /* ClkFeedBackScale */
- unsigned char *postscale
- /* ClkPostScale */ )
+static void pm3fb_calculate_clock(unsigned long reqclock,
+ unsigned char *prescale,
+ unsigned char *feedback,
+ unsigned char *postscale)
{
int f, pre, post;
unsigned long freq;
long freqerr = 1000;
- unsigned long actualclock = 0;
-
- DTRACE;
+ long currerr;
for (f = 1; f < 256; f++) {
for (pre = 1; pre < 256; pre++) {
for (post = 0; post < 5; post++) {
- freq =
- ((2 * refclock * f) /
- (pre * (1 << post)));
- if ((reqclock > freq - freqerr)
- && (reqclock < freq + freqerr)) {
- freqerr =
- (reqclock >
- freq) ? reqclock -
- freq : freq - reqclock;
+ freq = ((2*PM3_REF_CLOCK * f) >> post) / pre;
+ currerr = (reqclock > freq)
+ ? reqclock - freq
+ : freq - reqclock;
+ if (currerr < freqerr) {
+ freqerr = currerr;
*feedback = f;
*prescale = pre;
*postscale = post;
- actualclock = freq;
}
}
}
}
-
- return (actualclock);
}
-static int pm3fb_Shiftbpp(struct pm3fb_info *l_fb_info,
- unsigned long depth, int v)
+static inline int pm3fb_shift_bpp(unsigned long depth, int v)
{
- DTRACE;
-
switch (depth) {
case 8:
return (v >> 4);
@@ -918,181 +187,59 @@ static int pm3fb_Shiftbpp(struct pm3fb_info *l_fb_info,
case 32:
return (v >> 2);
}
- DPRINTK(1, "Unsupported depth %ld\n", depth);
- return (0);
-}
-
-static int pm3fb_Unshiftbpp(struct pm3fb_info *l_fb_info,
- unsigned long depth, int v)
-{
- DTRACE;
-
- switch (depth) {
- case 8:
- return (v << 4);
- case 12:
- case 15:
- case 16:
- return (v << 3);
- case 32:
- return (v << 2);
- }
- DPRINTK(1, "Unsupported depth %ld\n", depth);
- return (0);
-}
-
-static void pm3fb_mapIO(struct pm3fb_info *l_fb_info)
-{
- DTRACE;
-
- l_fb_info->vIOBase =
- ioremap((unsigned long) l_fb_info->pIOBase, PM3_REGS_SIZE);
- l_fb_info->v_fb =
- ioremap((unsigned long) l_fb_info->p_fb, l_fb_info->fb_size);
- DPRINTK(2, "IO mapping : IOBase %lx / %lx, fb %lx / %lx\n",
- (unsigned long) l_fb_info->pIOBase,
- (unsigned long) l_fb_info->vIOBase,
- (unsigned long) l_fb_info->p_fb,
- (unsigned long) l_fb_info->v_fb);
-}
-
-static void pm3fb_unmapIO(struct pm3fb_info *l_fb_info)
-{
- DTRACE;
-
- iounmap(l_fb_info->vIOBase);
- iounmap(l_fb_info->v_fb);
- l_fb_info->vIOBase = (unsigned char *) -1;
- l_fb_info->v_fb = (unsigned char *) -1;
-}
-
-#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
-static void pm3fb_show_cur_mode(struct pm3fb_info *l_fb_info)
-{
- DPRINTK(2, "PM3Aperture0: 0x%08x\n", PM3_READ_REG(PM3Aperture0));
- DPRINTK(2, "PM3Aperture1: 0x%08x\n", PM3_READ_REG(PM3Aperture1));
- DPRINTK(2, "PM3ByAperture1Mode: 0x%08x\n",
- PM3_READ_REG(PM3ByAperture1Mode));
- DPRINTK(2, "PM3ByAperture2Mode: 0x%08x\n",
- PM3_READ_REG(PM3ByAperture2Mode));
- DPRINTK(2, "PM3ChipConfig: 0x%08x\n", PM3_READ_REG(PM3ChipConfig));
- DPRINTK(2, "PM3FIFODis: 0x%08x\n", PM3_READ_REG(PM3FIFODis));
- DPRINTK(2, "PM3HTotal: 0x%08x\n", PM3_READ_REG(PM3HTotal));
- DPRINTK(2, "PM3HbEnd: 0x%08x\n", PM3_READ_REG(PM3HbEnd));
- DPRINTK(2, "PM3HgEnd: 0x%08x\n", PM3_READ_REG(PM3HgEnd));
- DPRINTK(2, "PM3HsEnd: 0x%08x\n", PM3_READ_REG(PM3HsEnd));
- DPRINTK(2, "PM3HsStart: 0x%08x\n", PM3_READ_REG(PM3HsStart));
- DPRINTK(2, "PM3MemBypassWriteMask: 0x%08x\n",
- PM3_READ_REG(PM3MemBypassWriteMask));
- DPRINTK(2, "PM3RD_IndexControl: 0x%08x\n",
- PM3_READ_REG(PM3RD_IndexControl));
- DPRINTK(2, "PM3ScreenBase: 0x%08x\n", PM3_READ_REG(PM3ScreenBase));
- DPRINTK(2, "PM3ScreenStride: 0x%08x\n",
- PM3_READ_REG(PM3ScreenStride));
- DPRINTK(2, "PM3VClkCtl: 0x%08x\n", PM3_READ_REG(PM3VClkCtl));
- DPRINTK(2, "PM3VTotal: 0x%08x\n", PM3_READ_REG(PM3VTotal));
- DPRINTK(2, "PM3VbEnd: 0x%08x\n", PM3_READ_REG(PM3VbEnd));
- DPRINTK(2, "PM3VideoControl: 0x%08x\n",
- PM3_READ_REG(PM3VideoControl));
- DPRINTK(2, "PM3VsEnd: 0x%08x\n", PM3_READ_REG(PM3VsEnd));
- DPRINTK(2, "PM3VsStart: 0x%08x\n", PM3_READ_REG(PM3VsStart));
-
- DPRINTK(2, "PM3RD_ColorFormat: %ld\n",
- PM3_READ_DAC_REG(PM3RD_ColorFormat));
- DPRINTK(2, "PM3RD_DACControl: %ld\n",
- PM3_READ_DAC_REG(PM3RD_DACControl));
- DPRINTK(2, "PM3RD_DClk0FeedbackScale: %ld\n",
- PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale));
- DPRINTK(2, "PM3RD_DClk0PostScale: %ld\n",
- PM3_READ_DAC_REG(PM3RD_DClk0PostScale));
- DPRINTK(2, "PM3RD_DClk0PreScale: %ld\n",
- PM3_READ_DAC_REG(PM3RD_DClk0PreScale));
- DPRINTK(2, "[not set] PM3RD_IndexControl: %ld\n",
- PM3_READ_DAC_REG(PM3RD_IndexControl));
- DPRINTK(2, "PM3RD_MiscControl: %ld\n",
- PM3_READ_DAC_REG(PM3RD_MiscControl));
- DPRINTK(2, "PM3RD_PixelSize: %ld\n",
- PM3_READ_DAC_REG(PM3RD_PixelSize));
- DPRINTK(2, "PM3RD_SyncControl: %ld\n",
- PM3_READ_DAC_REG(PM3RD_SyncControl));
-}
-
-#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2) */
-static void pm3fb_show_cur_timing(struct pm3fb_info *l_fb_info)
-{
- u16 subvendor, subdevice;
-
- if ((!pci_read_config_word
- (l_fb_info->dev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
- &&
- (!pci_read_config_word
- (l_fb_info->dev, PCI_SUBSYSTEM_ID, &subdevice))) {
- /* well, nothing... */
- } else {
- subvendor = subdevice = (u16)-1;
- }
-
- printk(KERN_INFO "pm3fb: memory timings for board #%ld (subvendor: 0x%hx, subdevice: 0x%hx)\n", l_fb_info->board_num, subvendor, subdevice);
- printk(KERN_INFO " PM3LocalMemCaps: 0x%08x\n",
- PM3_READ_REG(PM3LocalMemCaps));
- printk(KERN_INFO " PM3LocalMemTimings: 0x%08x\n",
- PM3_READ_REG(PM3LocalMemTimings));
- printk(KERN_INFO " PM3LocalMemControl: 0x%08x\n",
- PM3_READ_REG(PM3LocalMemControl));
- printk(KERN_INFO " PM3LocalMemRefresh: 0x%08x\n",
- PM3_READ_REG(PM3LocalMemRefresh));
- printk(KERN_INFO " PM3LocalMemPowerDown: 0x%08x\n",
- PM3_READ_REG(PM3LocalMemPowerDown));
+ DPRINTK("Unsupported depth %ld\n", depth);
+ return 0;
}
/* write the mode to registers */
-static void pm3fb_write_mode(struct pm3fb_info *l_fb_info)
+static void pm3fb_write_mode(struct fb_info *info)
{
+ struct pm3_par *par = info->par;
char tempsync = 0x00, tempmisc = 0x00;
- DTRACE;
-
- PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xffffffff);
- PM3_SLOW_WRITE_REG(PM3Aperture0, 0x00000000);
- PM3_SLOW_WRITE_REG(PM3Aperture1, 0x00000000);
- PM3_SLOW_WRITE_REG(PM3FIFODis, 0x00000007);
-
- PM3_SLOW_WRITE_REG(PM3HTotal,
- pm3fb_Shiftbpp(l_fb_info,
- l_fb_info->current_par->depth,
- l_fb_info->current_par->htotal -
- 1));
- PM3_SLOW_WRITE_REG(PM3HsEnd,
- pm3fb_Shiftbpp(l_fb_info,
- l_fb_info->current_par->depth,
- l_fb_info->current_par->hsend));
- PM3_SLOW_WRITE_REG(PM3HsStart,
- pm3fb_Shiftbpp(l_fb_info,
- l_fb_info->current_par->depth,
- l_fb_info->current_par->
+ const u32 hsstart = info->var.right_margin;
+ const u32 hsend = hsstart + info->var.hsync_len;
+ const u32 hbend = hsend + info->var.left_margin;
+ const u32 xres = (info->var.xres + 31) & ~31;
+ const u32 htotal = xres + hbend;
+ const u32 vsstart = info->var.lower_margin;
+ const u32 vsend = vsstart + info->var.vsync_len;
+ const u32 vbend = vsend + info->var.upper_margin;
+ const u32 vtotal = info->var.yres + vbend;
+ const u32 width = (info->var.xres_virtual + 7) & ~7;
+
+ PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
+ PM3_SLOW_WRITE_REG(par, PM3Aperture0, 0x00000000);
+ PM3_SLOW_WRITE_REG(par, PM3Aperture1, 0x00000000);
+ PM3_SLOW_WRITE_REG(par, PM3FIFODis, 0x00000007);
+
+ PM3_SLOW_WRITE_REG(par, PM3HTotal,
+ pm3fb_shift_bpp(info->var.bits_per_pixel,
+ htotal - 1));
+ PM3_SLOW_WRITE_REG(par, PM3HsEnd,
+ pm3fb_shift_bpp(info->var.bits_per_pixel,
+ hsend));
+ PM3_SLOW_WRITE_REG(par, PM3HsStart,
+ pm3fb_shift_bpp(info->var.bits_per_pixel,
hsstart));
- PM3_SLOW_WRITE_REG(PM3HbEnd,
- pm3fb_Shiftbpp(l_fb_info,
- l_fb_info->current_par->depth,
- l_fb_info->current_par->hbend));
- PM3_SLOW_WRITE_REG(PM3HgEnd,
- pm3fb_Shiftbpp(l_fb_info,
- l_fb_info->current_par->depth,
- l_fb_info->current_par->hbend));
- PM3_SLOW_WRITE_REG(PM3ScreenStride,
- pm3fb_Shiftbpp(l_fb_info,
- l_fb_info->current_par->depth,
- l_fb_info->current_par->stride));
- PM3_SLOW_WRITE_REG(PM3VTotal, l_fb_info->current_par->vtotal - 1);
- PM3_SLOW_WRITE_REG(PM3VsEnd, l_fb_info->current_par->vsend - 1);
- PM3_SLOW_WRITE_REG(PM3VsStart,
- l_fb_info->current_par->vsstart - 1);
- PM3_SLOW_WRITE_REG(PM3VbEnd, l_fb_info->current_par->vbend);
-
- switch (l_fb_info->current_par->depth) {
+ PM3_SLOW_WRITE_REG(par, PM3HbEnd,
+ pm3fb_shift_bpp(info->var.bits_per_pixel,
+ hbend));
+ PM3_SLOW_WRITE_REG(par, PM3HgEnd,
+ pm3fb_shift_bpp(info->var.bits_per_pixel,
+ hbend));
+ PM3_SLOW_WRITE_REG(par, PM3ScreenStride,
+ pm3fb_shift_bpp(info->var.bits_per_pixel,
+ width));
+ PM3_SLOW_WRITE_REG(par, PM3VTotal, vtotal - 1);
+ PM3_SLOW_WRITE_REG(par, PM3VsEnd, vsend - 1);
+ PM3_SLOW_WRITE_REG(par, PM3VsStart, vsstart - 1);
+ PM3_SLOW_WRITE_REG(par, PM3VbEnd, vbend);
+
+ switch (info->var.bits_per_pixel) {
case 8:
- PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_8BIT);
- PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_8BIT);
break;
@@ -1100,15 +247,15 @@ static void pm3fb_write_mode(struct pm3fb_info *l_fb_info)
case 15:
case 16:
#ifndef __BIG_ENDIAN
- PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_16BIT);
- PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_16BIT);
#else
- PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_16BIT |
PM3ByApertureMode_BYTESWAP_BADC);
- PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_16BIT |
PM3ByApertureMode_BYTESWAP_BADC);
#endif /* ! __BIG_ENDIAN */
@@ -1116,23 +263,23 @@ static void pm3fb_write_mode(struct pm3fb_info *l_fb_info)
case 32:
#ifndef __BIG_ENDIAN
- PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_32BIT);
- PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_32BIT);
#else
- PM3_SLOW_WRITE_REG(PM3ByAperture1Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_32BIT |
PM3ByApertureMode_BYTESWAP_DCBA);
- PM3_SLOW_WRITE_REG(PM3ByAperture2Mode,
+ PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_32BIT |
PM3ByApertureMode_BYTESWAP_DCBA);
#endif /* ! __BIG_ENDIAN */
break;
default:
- DPRINTK(1, "Unsupported depth %d\n",
- l_fb_info->current_par->depth);
+ DPRINTK("Unsupported depth %d\n",
+ info->var.bits_per_pixel);
break;
}
@@ -1143,95 +290,86 @@ static void pm3fb_write_mode(struct pm3fb_info *l_fb_info)
* sync options in PM3RD_SyncControl. --rmk
*/
{
- unsigned int video = l_fb_info->current_par->video;
+ unsigned int video = par->video;
video &= ~(PM3VideoControl_HSYNC_MASK |
PM3VideoControl_VSYNC_MASK);
video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
PM3VideoControl_VSYNC_ACTIVE_HIGH;
- PM3_SLOW_WRITE_REG(PM3VideoControl, video);
+ PM3_SLOW_WRITE_REG(par, PM3VideoControl, video);
}
- PM3_SLOW_WRITE_REG(PM3VClkCtl,
- (PM3_READ_REG(PM3VClkCtl) & 0xFFFFFFFC));
- PM3_SLOW_WRITE_REG(PM3ScreenBase, l_fb_info->current_par->base);
- PM3_SLOW_WRITE_REG(PM3ChipConfig,
- (PM3_READ_REG(PM3ChipConfig) & 0xFFFFFFFD));
+ PM3_SLOW_WRITE_REG(par, PM3VClkCtl,
+ (PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC));
+ PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
+ PM3_SLOW_WRITE_REG(par, PM3ChipConfig,
+ (PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD));
{
- unsigned char m; /* ClkPreScale */
- unsigned char n; /* ClkFeedBackScale */
- unsigned char p; /* ClkPostScale */
- (void)pm3fb_CalculateClock(l_fb_info, l_fb_info->current_par->pixclock, PM3_REF_CLOCK, &m, &n, &p);
-
- DPRINTK(2,
- "Pixclock: %d, Pre: %d, Feedback: %d, Post: %d\n",
- l_fb_info->current_par->pixclock, (int) m, (int) n,
- (int) p);
-
- PM3_WRITE_DAC_REG(PM3RD_DClk0PreScale, m);
- PM3_WRITE_DAC_REG(PM3RD_DClk0FeedbackScale, n);
- PM3_WRITE_DAC_REG(PM3RD_DClk0PostScale, p);
+ unsigned char uninitialized_var(m); /* ClkPreScale */
+ unsigned char uninitialized_var(n); /* ClkFeedBackScale */
+ unsigned char uninitialized_var(p); /* ClkPostScale */
+ unsigned long pixclock = PICOS2KHZ(info->var.pixclock);
+
+ (void)pm3fb_calculate_clock(pixclock, &m, &n, &p);
+
+ DPRINTK("Pixclock: %ld, Pre: %d, Feedback: %d, Post: %d\n",
+ pixclock, (int) m, (int) n, (int) p);
+
+ PM3_WRITE_DAC_REG(par, PM3RD_DClk0PreScale, m);
+ PM3_WRITE_DAC_REG(par, PM3RD_DClk0FeedbackScale, n);
+ PM3_WRITE_DAC_REG(par, PM3RD_DClk0PostScale, p);
}
/*
- PM3_WRITE_DAC_REG(PM3RD_IndexControl, 0x00);
+ PM3_WRITE_DAC_REG(par, PM3RD_IndexControl, 0x00);
*/
/*
- PM3_SLOW_WRITE_REG(PM3RD_IndexControl, 0x00);
+ PM3_SLOW_WRITE_REG(par, PM3RD_IndexControl, 0x00);
*/
- if ((l_fb_info->current_par->video & PM3VideoControl_HSYNC_MASK) ==
+ if ((par->video & PM3VideoControl_HSYNC_MASK) ==
PM3VideoControl_HSYNC_ACTIVE_HIGH)
tempsync |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH;
- if ((l_fb_info->current_par->video & PM3VideoControl_VSYNC_MASK) ==
+ if ((par->video & PM3VideoControl_VSYNC_MASK) ==
PM3VideoControl_VSYNC_ACTIVE_HIGH)
tempsync |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH;
-
- PM3_WRITE_DAC_REG(PM3RD_SyncControl, tempsync);
- DPRINTK(2, "PM3RD_SyncControl: %d\n", tempsync);
-
- if (flatpanel[l_fb_info->board_num])
- {
- PM3_WRITE_DAC_REG(PM3RD_DACControl, PM3RD_DACControl_BLANK_PEDESTAL_ENABLE);
- PM3_WAIT(2);
- PM3_WRITE_REG(PM3VSConfiguration, 0x06);
- PM3_WRITE_REG(0x5a00, 1 << 14); /* black magic... */
- tempmisc = PM3RD_MiscControl_VSB_OUTPUT_ENABLE;
- }
- else
- PM3_WRITE_DAC_REG(PM3RD_DACControl, 0x00);
- switch (l_fb_info->current_par->depth) {
+ PM3_WRITE_DAC_REG(par, PM3RD_SyncControl, tempsync);
+ DPRINTK("PM3RD_SyncControl: %d\n", tempsync);
+
+ PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00);
+
+ switch (info->var.bits_per_pixel) {
case 8:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+ PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
PM3RD_PixelSize_8_BIT_PIXELS);
- PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+ PM3_WRITE_DAC_REG(par, PM3RD_ColorFormat,
PM3RD_ColorFormat_CI8_COLOR |
PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);
tempmisc |= PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
break;
case 12:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+ PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
PM3RD_PixelSize_16_BIT_PIXELS);
- PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+ PM3_WRITE_DAC_REG(par, PM3RD_ColorFormat,
PM3RD_ColorFormat_4444_COLOR |
PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
- break;
+ break;
case 15:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+ PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
PM3RD_PixelSize_16_BIT_PIXELS);
- PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+ PM3_WRITE_DAC_REG(par, PM3RD_ColorFormat,
PM3RD_ColorFormat_5551_FRONT_COLOR |
PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
- break;
+ break;
case 16:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+ PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
PM3RD_PixelSize_16_BIT_PIXELS);
- PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+ PM3_WRITE_DAC_REG(par, PM3RD_ColorFormat,
PM3RD_ColorFormat_565_FRONT_COLOR |
PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
@@ -1239,1936 +377,280 @@ static void pm3fb_write_mode(struct pm3fb_info *l_fb_info)
PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
break;
case 32:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
+ PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
PM3RD_PixelSize_32_BIT_PIXELS);
- PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
+ PM3_WRITE_DAC_REG(par, PM3RD_ColorFormat,
PM3RD_ColorFormat_8888_COLOR |
PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);
tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
break;
}
- PM3_WRITE_DAC_REG(PM3RD_MiscControl, tempmisc);
-
- PM3_SHOW_CUR_MODE;
+ PM3_WRITE_DAC_REG(par, PM3RD_MiscControl, tempmisc);
}
-static void pm3fb_read_mode(struct pm3fb_info *l_fb_info,
- struct pm3fb_par *curpar)
-{
- unsigned long pixsize1, pixsize2, clockused;
- unsigned long pre, feedback, post;
-
- DTRACE;
-
- clockused = PM3_READ_REG(PM3VClkCtl);
+/*
+ * hardware independent functions
+ */
+int pm3fb_init(void);
+int pm3fb_setup(char*);
- switch (clockused) {
- case 3:
- pre = PM3_READ_DAC_REG(PM3RD_DClk3PreScale);
- feedback = PM3_READ_DAC_REG(PM3RD_DClk3FeedbackScale);
- post = PM3_READ_DAC_REG(PM3RD_DClk3PostScale);
+static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ u32 lpitch;
- DPRINTK(2,
- "DClk3 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
- pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
- feedback,
- post));
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ switch(var->bits_per_pixel) {
+ case 8:
+ var->red.length = var->green.length = var->blue.length = 8;
+ var->red.offset = var->green.offset = var->blue.offset = 0;
break;
- case 2:
- pre = PM3_READ_DAC_REG(PM3RD_DClk2PreScale);
- feedback = PM3_READ_DAC_REG(PM3RD_DClk2FeedbackScale);
- post = PM3_READ_DAC_REG(PM3RD_DClk2PostScale);
-
- DPRINTK(2,
- "DClk2 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
- pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
- feedback,
- post));
+ case 12:
+ var->red.offset = 8;
+ var->red.length = 4;
+ var->green.offset = 4;
+ var->green.length = 4;
+ var->blue.offset = 0;
+ var->blue.length = 4;
+ var->transp.offset = 12;
+ var->transp.length = 4;
+ case 15:
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 15;
+ var->transp.length = 1;
break;
- case 1:
- pre = PM3_READ_DAC_REG(PM3RD_DClk1PreScale);
- feedback = PM3_READ_DAC_REG(PM3RD_DClk1FeedbackScale);
- post = PM3_READ_DAC_REG(PM3RD_DClk1PostScale);
-
- DPRINTK(2,
- "DClk1 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
- pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
- feedback,
- post));
+ case 16:
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
break;
- case 0:
- pre = PM3_READ_DAC_REG(PM3RD_DClk0PreScale);
- feedback = PM3_READ_DAC_REG(PM3RD_DClk0FeedbackScale);
- post = PM3_READ_DAC_REG(PM3RD_DClk0PostScale);
-
- DPRINTK(2,
- "DClk0 parameter: Pre: %ld, Feedback: %ld, Post: %ld ; giving pixclock: %ld\n",
- pre, feedback, post, PM3_SCALE_TO_CLOCK(pre,
- feedback,
- post));
+ case 32:
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 8;
break;
default:
- pre = feedback = post = 0;
- DPRINTK(1, "Unknowk D clock used : %ld\n", clockused);
- break;
- }
-
- curpar->pixclock = PM3_SCALE_TO_CLOCK(pre, feedback, post);
-
- pixsize1 =
- PM3ByApertureMode_PIXELSIZE_MASK &
- (PM3_READ_REG(PM3ByAperture1Mode));
- pixsize2 =
- PM3ByApertureMode_PIXELSIZE_MASK &
- (PM3_READ_REG(PM3ByAperture2Mode));
-
- DASSERT((pixsize1 == pixsize2),
- "pixsize the same in both aperture\n");
-
- if (pixsize1 & PM3ByApertureMode_PIXELSIZE_32BIT)
- curpar->depth = 32;
- else if (pixsize1 & PM3ByApertureMode_PIXELSIZE_16BIT)
- {
- curpar->depth = 16;
- }
- else
- curpar->depth = 8;
-
- /* not sure if I need to add one on the next ; it give better result with */
- curpar->htotal =
- pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
- 1 + PM3_READ_REG(PM3HTotal));
- curpar->hsend =
- pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
- PM3_READ_REG(PM3HsEnd));
- curpar->hsstart =
- pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
- PM3_READ_REG(PM3HsStart));
- curpar->hbend =
- pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
- PM3_READ_REG(PM3HbEnd));
-
- curpar->stride =
- pm3fb_Unshiftbpp(l_fb_info, curpar->depth,
- PM3_READ_REG(PM3ScreenStride));
-
- curpar->vtotal = 1 + PM3_READ_REG(PM3VTotal);
- curpar->vsend = 1 + PM3_READ_REG(PM3VsEnd);
- curpar->vsstart = 1 + PM3_READ_REG(PM3VsStart);
- curpar->vbend = PM3_READ_REG(PM3VbEnd);
-
- curpar->video = PM3_READ_REG(PM3VideoControl);
-
- curpar->base = PM3_READ_REG(PM3ScreenBase);
- curpar->width = curpar->htotal - curpar->hbend; /* make virtual == displayed resolution */
- curpar->height = curpar->vtotal - curpar->vbend;
-
- DPRINTK(2, "Found : %d * %d, %d Khz, stride is %08x\n",
- curpar->width, curpar->height, curpar->pixclock,
- curpar->stride);
-}
-
-static unsigned long pm3fb_size_memory(struct pm3fb_info *l_fb_info)
-{
- unsigned long memsize = 0, tempBypass, i, temp1, temp2;
- u16 subvendor, subdevice;
- pm3fb_timing_result ptr;
-
- DTRACE;
-
- l_fb_info->fb_size = 64 * 1024 * 1024; /* pm3 aperture always 64 MB */
- pm3fb_mapIO(l_fb_info); /* temporary map IO */
-
- DASSERT((l_fb_info->vIOBase != NULL),
- "IO successfully mapped before mem detect\n");
- DASSERT((l_fb_info->v_fb != NULL),
- "FB successfully mapped before mem detect\n");
-
- /* card-specific stuff, *before* accessing *any* FB memory */
- if ((!pci_read_config_word
- (l_fb_info->dev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
- &&
- (!pci_read_config_word
- (l_fb_info->dev, PCI_SUBSYSTEM_ID, &subdevice))) {
- i = 0; l_fb_info->board_type = 0;
- while ((cardbase[i].cardname[0]) && !(l_fb_info->board_type)) {
- if ((cardbase[i].subvendor == subvendor) &&
- (cardbase[i].subdevice == subdevice) &&
- (cardbase[i].func == PCI_FUNC(l_fb_info->dev->devfn))) {
- DPRINTK(2, "Card #%ld is an %s\n",
- l_fb_info->board_num,
- cardbase[i].cardname);
- if (cardbase[i].specific_setup)
- cardbase[i].specific_setup(l_fb_info);
- l_fb_info->board_type = i;
- }
- i++;
- }
- if (!l_fb_info->board_type) {
- DPRINTK(1, "Card #%ld is an unknown 0x%04x / 0x%04x\n",
- l_fb_info->board_num, subvendor, subdevice);
- }
- } else {
- printk(KERN_ERR "pm3fb: Error: pci_read_config_word failed, board #%ld\n",
- l_fb_info->board_num);
- }
-
- if (printtimings)
- pm3fb_show_cur_timing(l_fb_info);
-
- /* card-specific setup is done, we preserve the final
- memory timing for future reference */
- if ((ptr = pm3fb_preserve_memory_timings(l_fb_info)) == pm3fb_timing_problem) { /* memory timings were wrong ! oops.... */
- return(0);
- }
-
- tempBypass = PM3_READ_REG(PM3MemBypassWriteMask);
-
- DPRINTK(2, "PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
-
- PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xFFFFFFFF);
-
- /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
- for (i = 0; i < 32; i++) {
- fb_writel(i * 0x00345678,
- (l_fb_info->v_fb + (i * 1048576)));
- mb();
- temp1 = fb_readl((l_fb_info->v_fb + (i * 1048576)));
-
- /* Let's check for wrapover, write will fail at 16MB boundary */
- if (temp1 == (i * 0x00345678))
- memsize = i;
- else
- break;
- }
-
- DPRINTK(2, "First detect pass already got %ld MB\n", memsize + 1);
-
- if (memsize == i) {
- for (i = 0; i < 32; i++) {
- /* Clear first 32MB ; 0 is 0, no need to byteswap */
- writel(0x0000000,
- (l_fb_info->v_fb + (i * 1048576)));
- mb();
- }
-
- for (i = 32; i < 64; i++) {
- fb_writel(i * 0x00345678,
- (l_fb_info->v_fb + (i * 1048576)));
- mb();
- temp1 =
- fb_readl((l_fb_info->v_fb + (i * 1048576)));
- temp2 =
- fb_readl((l_fb_info->v_fb +
- ((i - 32) * 1048576)));
- if ((temp1 == (i * 0x00345678)) && (temp2 == 0)) /* different value, different RAM... */
- memsize = i;
- else
- break;
- }
- }
-
- DPRINTK(2, "Second detect pass got %ld MB\n", memsize + 1);
-
- PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, tempBypass);
-
- pm3fb_unmapIO(l_fb_info);
- memsize = 1048576 * (memsize + 1);
-
- DPRINTK(2, "Returning 0x%08lx bytes\n", memsize);
-
- if (forcesize[l_fb_info->board_num] && ((forcesize[l_fb_info->board_num] * 1048576) != memsize))
- {
- printk(KERN_WARNING "pm3fb: mismatch between probed (%ld MB) and specified (%hd MB) memory size, using SPECIFIED !\n", memsize, forcesize[l_fb_info->board_num]);
- memsize = 1048576 * forcesize[l_fb_info->board_num];
- }
-
- l_fb_info->fb_size = memsize;
-
- if (ptr == pm3fb_timing_retry)
- {
- printk(KERN_WARNING "pm3fb: retrying memory timings check");
- if (pm3fb_try_memory_timings(l_fb_info) == pm3fb_timing_problem)
- return(0);
- }
-
- return (memsize);
-}
-
-static void pm3fb_clear_memory(struct pm3fb_info *l_fb_info, u32 cc)
-{
- int i;
-
- DTRACE;
-
- for (i = 0; i < (l_fb_info->fb_size / sizeof(u32)) ; i++) /* clear entire FB memory to black */
- {
- fb_writel(cc, (l_fb_info->v_fb + (i * sizeof(u32))));
+ DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
+ return -EINVAL;
}
-}
-
-static void pm3fb_clear_colormap(struct pm3fb_info *l_fb_info, unsigned char r, unsigned char g, unsigned char b)
-{
- int i;
-
- DTRACE;
-
- for (i = 0; i < 256 ; i++) /* fill color map with white */
- pm3fb_set_color(l_fb_info, i, r, g, b);
-
-}
-
-/* common initialisation */
-static void pm3fb_common_init(struct pm3fb_info *l_fb_info)
-{
- DTRACE;
-
- DPRINTK(2, "Initializing board #%ld @ %lx\n", l_fb_info->board_num,
- (unsigned long) l_fb_info);
-
- strcpy(l_fb_info->gen.info.modename, permedia3_name);
- disp[l_fb_info->board_num].scrollmode = 0; /* SCROLL_YNOMOVE; *//* 0 means "let fbcon choose" */
- l_fb_info->gen.parsize = sizeof(struct pm3fb_par);
- l_fb_info->gen.info.changevar = NULL;
- l_fb_info->gen.info.fbops = &pm3fb_ops;
- l_fb_info->gen.info.disp = &(disp[l_fb_info->board_num]);
- if (fontn[l_fb_info->board_num][0])
- strcpy(l_fb_info->gen.info.fontname,
- fontn[l_fb_info->board_num]);
- l_fb_info->gen.info.switch_con = &fbgen_switch;
- l_fb_info->gen.info.updatevar = &fbgen_update_var; /* */
- l_fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
-
- pm3fb_mapIO(l_fb_info);
-
- pm3fb_clear_memory(l_fb_info, 0);
- pm3fb_clear_colormap(l_fb_info, 0, 0, 0);
-
- (void) fbgen_get_var(&(disp[l_fb_info->board_num]).var, -1,
- &l_fb_info->gen.info);
+ var->height = var->width = -1;
- if (depth[l_fb_info->board_num]) /* override mode-defined depth */
- {
- pm3fb_encode_depth(&(disp[l_fb_info->board_num]).var, depth[l_fb_info->board_num]);
- (disp[l_fb_info->board_num]).var.bits_per_pixel = depth2bpp(depth[l_fb_info->board_num]);
+ if (var->xres != var->xres_virtual) {
+ DPRINTK("virtual x resolution != physical x resolution not supported\n");
+ return -EINVAL;
}
- (void) fbgen_do_set_var(&(disp[l_fb_info->board_num]).var, 1,
- &l_fb_info->gen);
-
- fbgen_set_disp(-1, &l_fb_info->gen);
-
- do_install_cmap(0, &l_fb_info->gen.info);
-
- if (register_framebuffer(&l_fb_info->gen.info) < 0) {
- DPRINTK(1, "Couldn't register framebuffer\n");
- return;
+ if (var->yres > var->yres_virtual) {
+ DPRINTK("virtual y resolution < physical y resolution not possible\n");
+ return -EINVAL;
}
- PM3_WRITE_DAC_REG(PM3RD_CursorMode,
- PM3RD_CursorMode_CURSOR_DISABLE);
-
- PM3_SHOW_CUR_MODE;
-
- pm3fb_write_mode(l_fb_info);
-
- printk("fb%d: %s, using %uK of video memory (%s)\n",
- l_fb_info->gen.info.node,
- permedia3_name, (u32) (l_fb_info->fb_size >> 10),
- cardbase[l_fb_info->board_type].cardname);
-}
-
-/* **************************************************** */
-/* ***** accelerated permedia3-specific functions ***** */
-/* **************************************************** */
-#ifdef PM3FB_USE_ACCEL
-static void pm3fb_wait_pm3(struct pm3fb_info *l_fb_info)
-{
- DTRACE;
-
- PM3_SLOW_WRITE_REG(PM3FilterMode, PM3FilterModeSync);
- PM3_SLOW_WRITE_REG(PM3Sync, 0);
- mb();
- do {
- while ((PM3_READ_REG(PM3OutFIFOWords)) == 0);
- rmb();
- } while ((PM3_READ_REG(PM3OutputFifo)) != PM3Sync_Tag);
-}
-
-static void pm3fb_init_engine(struct pm3fb_info *l_fb_info)
-{
- PM3_SLOW_WRITE_REG(PM3FilterMode, PM3FilterModeSync);
- PM3_SLOW_WRITE_REG(PM3StatisticMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3DeltaMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3RasterizerMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3ScissorMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3LineStippleMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3AreaStippleMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3GIDMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3DepthMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3StencilMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3StencilData, 0x0);
- PM3_SLOW_WRITE_REG(PM3ColorDDAMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureCoordMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureIndexMode0, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureIndexMode1, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureReadMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3LUTMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureFilterMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureCompositeMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureApplicationMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureCompositeColorMode1, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureCompositeAlphaMode1, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureCompositeColorMode0, 0x0);
- PM3_SLOW_WRITE_REG(PM3TextureCompositeAlphaMode0, 0x0);
- PM3_SLOW_WRITE_REG(PM3FogMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3ChromaTestMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3AlphaTestMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3AntialiasMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3YUVMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3AlphaBlendColorMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3AlphaBlendAlphaMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3DitherMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3LogicalOpMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3RouterMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3Window, 0x0);
-
- PM3_SLOW_WRITE_REG(PM3Config2D, 0x0);
-
- PM3_SLOW_WRITE_REG(PM3SpanColorMask, 0xffffffff);
-
- PM3_SLOW_WRITE_REG(PM3XBias, 0x0);
- PM3_SLOW_WRITE_REG(PM3YBias, 0x0);
- PM3_SLOW_WRITE_REG(PM3DeltaControl, 0x0);
-
- PM3_SLOW_WRITE_REG(PM3BitMaskPattern, 0xffffffff);
-
- PM3_SLOW_WRITE_REG(PM3FBDestReadEnables,
- PM3FBDestReadEnables_E(0xff) |
- PM3FBDestReadEnables_R(0xff) |
- PM3FBDestReadEnables_ReferenceAlpha(0xff));
- PM3_SLOW_WRITE_REG(PM3FBDestReadBufferAddr0, 0x0);
- PM3_SLOW_WRITE_REG(PM3FBDestReadBufferOffset0, 0x0);
- PM3_SLOW_WRITE_REG(PM3FBDestReadBufferWidth0,
- PM3FBDestReadBufferWidth_Width(l_fb_info->
- current_par->
- width));
-
- PM3_SLOW_WRITE_REG(PM3FBDestReadMode,
- PM3FBDestReadMode_ReadEnable |
- PM3FBDestReadMode_Enable0);
- PM3_SLOW_WRITE_REG(PM3FBSourceReadBufferAddr, 0x0);
- PM3_SLOW_WRITE_REG(PM3FBSourceReadBufferOffset, 0x0);
- PM3_SLOW_WRITE_REG(PM3FBSourceReadBufferWidth,
- PM3FBSourceReadBufferWidth_Width(l_fb_info->
- current_par->
- width));
- PM3_SLOW_WRITE_REG(PM3FBSourceReadMode,
- PM3FBSourceReadMode_Blocking |
- PM3FBSourceReadMode_ReadEnable);
-
- {
- unsigned long rm = 1;
- switch (l_fb_info->current_par->depth) {
- case 8:
- PM3_SLOW_WRITE_REG(PM3PixelSize,
- PM3PixelSize_GLOBAL_8BIT);
- break;
- case 12:
- case 15:
- case 16:
- PM3_SLOW_WRITE_REG(PM3PixelSize,
- PM3PixelSize_GLOBAL_16BIT);
- break;
- case 32:
- PM3_SLOW_WRITE_REG(PM3PixelSize,
- PM3PixelSize_GLOBAL_32BIT);
- break;
- default:
- DPRINTK(1, "Unsupported depth %d\n",
- l_fb_info->current_par->depth);
- break;
- }
- PM3_SLOW_WRITE_REG(PM3RasterizerMode, rm);
+ if (var->xoffset) {
+ DPRINTK("xoffset not supported\n");
+ return -EINVAL;
}
- PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0xffffffff);
- PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xffffffff);
- PM3_SLOW_WRITE_REG(PM3FBWriteMode,
- PM3FBWriteMode_WriteEnable |
- PM3FBWriteMode_OpaqueSpan |
- PM3FBWriteMode_Enable0);
- PM3_SLOW_WRITE_REG(PM3FBWriteBufferAddr0, 0x0);
- PM3_SLOW_WRITE_REG(PM3FBWriteBufferOffset0, 0x0);
- PM3_SLOW_WRITE_REG(PM3FBWriteBufferWidth0,
- PM3FBWriteBufferWidth_Width(l_fb_info->
- current_par->
- width));
-
- PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, 0x0);
- {
- unsigned long sofb = (8UL * l_fb_info->fb_size) /
- ((depth2bpp(l_fb_info->current_par->depth))
- * l_fb_info->current_par->width); /* size in lines of FB */
- if (sofb > 4095)
- PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, 4095);
- else
- PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, sofb);
-
- switch (l_fb_info->current_par->depth) {
- case 8:
- PM3_SLOW_WRITE_REG(PM3DitherMode,
- (1 << 10) | (2 << 3));
- break;
- case 12:
- case 15:
- case 16:
- PM3_SLOW_WRITE_REG(PM3DitherMode,
- (1 << 10) | (1 << 3));
- break;
- case 32:
- PM3_SLOW_WRITE_REG(PM3DitherMode,
- (1 << 10) | (0 << 3));
- break;
- default:
- DPRINTK(1, "Unsupported depth %d\n",
- l_fb_info->current_par->depth);
- break;
- }
+ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+ DPRINTK("interlace not supported\n");
+ return -EINVAL;
}
- PM3_SLOW_WRITE_REG(PM3dXDom, 0x0);
- PM3_SLOW_WRITE_REG(PM3dXSub, 0x0);
- PM3_SLOW_WRITE_REG(PM3dY, (1 << 16));
- PM3_SLOW_WRITE_REG(PM3StartXDom, 0x0);
- PM3_SLOW_WRITE_REG(PM3StartXSub, 0x0);
- PM3_SLOW_WRITE_REG(PM3StartY, 0x0);
- PM3_SLOW_WRITE_REG(PM3Count, 0x0);
-
-/* Disable LocalBuffer. better safe than sorry */
- PM3_SLOW_WRITE_REG(PM3LBDestReadMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3LBDestReadEnables, 0x0);
- PM3_SLOW_WRITE_REG(PM3LBSourceReadMode, 0x0);
- PM3_SLOW_WRITE_REG(PM3LBWriteMode, 0x0);
-
- pm3fb_wait_pm3(l_fb_info);
-}
+ var->xres = (var->xres + 31) & ~31; /* could sometimes be 8 */
+ lpitch = var->xres * ((var->bits_per_pixel + 7)>>3);
-#ifdef FBCON_HAS_CFB32
-static void pm3fb_cfb32_clear(struct vc_data *conp,
- struct display *p,
- int sy, int sx, int height, int width)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- u32 c;
-
- DTRACE;
-
- sx = sx * fontwidth(p);
- width = width * fontwidth(p);
- sy = sy * fontheight(p);
- height = height * fontheight(p);
- c = ((u32 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- /* block fills in 32bpp are hard, but in low res (width <= 1600 :-)
- we can use 16bpp operations, but not if NoWriteMask is on (SDRAM) */
- if ((l_fb_info->current_par->width > 1600) ||
- (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)) {
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3ForegroundColor, c);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(sx)) |
- (PM3RectanglePosition_YOffset(sy)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(width)) |
- (PM3Render2D_Height(height)));
- } else {
- PM3_WAIT(8);
-
- PM3_WRITE_REG(PM3FBBlockColor, c);
-
- PM3_WRITE_REG(PM3PixelSize, PM3PixelSize_GLOBAL_16BIT);
-
- PM3_WRITE_REG(PM3FBWriteBufferWidth0,
- PM3FBWriteBufferWidth_Width(l_fb_info->
- current_par->
- width << 1));
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(sx << 1)) |
- (PM3RectanglePosition_YOffset(sy)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- (PM3Render2D_Width(width << 1)) |
- (PM3Render2D_Height(height)));
-
- PM3_WRITE_REG(PM3FBWriteBufferWidth0,
- PM3FBWriteBufferWidth_Width(l_fb_info->
- current_par->
- width));
-
- PM3_WRITE_REG(PM3PixelSize, PM3PixelSize_GLOBAL_32BIT);
+ if (var->xres < 200 || var->xres > 2048) {
+ DPRINTK("width not supported: %u\n", var->xres);
+ return -EINVAL;
}
- pm3fb_wait_pm3(l_fb_info);
-}
-
-static void pm3fb_cfb32_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- int sx, sy;
- u32 c;
-
- DTRACE;
-
- sx = conp->vc_cols * fontwidth(p); /* right margin */
- sy = conp->vc_rows * fontheight(p); /* bottom margin */
- c = ((u32 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- if (!bottom_only) { /* right margin top->bottom */
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3ForegroundColor, c);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset
- (p->var.xoffset +
- sx)) | (PM3RectanglePosition_YOffset(p->
- var.
- yoffset)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(p->var.xres - sx)) |
- (PM3Render2D_Height(p->var.yres)));
+ if (var->yres < 200 || var->yres > 4095) {
+ DPRINTK("height not supported: %u\n", var->yres);
+ return -EINVAL;
}
- /* bottom margin left -> right */
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3ForegroundColor, c);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(p->var.xoffset)) |
- (PM3RectanglePosition_YOffset(p->var.yoffset + sy)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(p->var.xres)) |
- (PM3Render2D_Height(p->var.yres - sy)));
-
- pm3fb_wait_pm3(l_fb_info);
-}
-#endif /* FBCON_HAS_CFB32 */
-#ifdef FBCON_HAS_CFB16
-static void pm3fb_cfb16_clear(struct vc_data *conp,
- struct display *p,
- int sy, int sx, int height, int width)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- u32 c;
-
- DTRACE;
-
- sx = sx * fontwidth(p);
- width = width * fontwidth(p);
- sy = sy * fontheight(p);
- height = height * fontheight(p);
- c = ((u16 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
- c = c | (c << 16);
-
- PM3_WAIT(4);
-
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_WRITE_REG(PM3ForegroundColor, c);
- else
- PM3_WRITE_REG(PM3FBBlockColor, c);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(sx)) |
- (PM3RectanglePosition_YOffset(sy)));
-
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(width)) |
- (PM3Render2D_Height(height)));
- else
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- (PM3Render2D_Width(width)) |
- (PM3Render2D_Height(height)));
-
- pm3fb_wait_pm3(l_fb_info);
-}
-
-static void pm3fb_cfb16_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- int sx, sy;
- u32 c;
-
- DTRACE;
-
- sx = conp->vc_cols * fontwidth(p); /* right margin */
- sy = conp->vc_rows * fontheight(p); /* bottom margin */
- c = ((u16 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
- c = c | (c << 16);
-
- if (!bottom_only) { /* right margin top->bottom */
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_WRITE_REG(PM3ForegroundColor, c);
- else
- PM3_WRITE_REG(PM3FBBlockColor, c);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset
- (p->var.xoffset +
- sx)) | (PM3RectanglePosition_YOffset(p->
- var.
- yoffset)));
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(p->var.xres - sx)) |
- (PM3Render2D_Height(p->var.yres)));
- else
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- (PM3Render2D_Width(p->var.xres - sx)) |
- (PM3Render2D_Height(p->var.yres)));
+ if (lpitch * var->yres_virtual > info->fix.smem_len) {
+ DPRINTK("no memory for screen (%ux%ux%u)\n",
+ var->xres, var->yres_virtual, var->bits_per_pixel);
+ return -EINVAL;
}
-
- /* bottom margin left -> right */
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_WRITE_REG(PM3ForegroundColor, c);
- else
- PM3_WRITE_REG(PM3FBBlockColor, c);
-
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(p->var.xoffset)) |
- (PM3RectanglePosition_YOffset(p->var.yoffset + sy)));
-
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(p->var.xres)) |
- (PM3Render2D_Height(p->var.yres - sy)));
- else
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- (PM3Render2D_Width(p->var.xres)) |
- (PM3Render2D_Height(p->var.yres - sy)));
-
- pm3fb_wait_pm3(l_fb_info);
-}
-#endif /* FBCON_HAS_CFB16 */
-#ifdef FBCON_HAS_CFB8
-static void pm3fb_cfb8_clear(struct vc_data *conp,
- struct display *p,
- int sy, int sx, int height, int width)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- u32 c;
-
- DTRACE;
-
- sx = sx * fontwidth(p);
- width = width * fontwidth(p);
- sy = sy * fontheight(p);
- height = height * fontheight(p);
-
- c = attr_bgcol_ec(p, conp);
- c |= c << 8;
- c |= c << 16;
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3ForegroundColor, c);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(sx)) |
- (PM3RectanglePosition_YOffset(sy)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(width)) |
- (PM3Render2D_Height(height)));
-
- pm3fb_wait_pm3(l_fb_info);
-}
-
-static void pm3fb_cfb8_clear_margins(struct vc_data *conp,
- struct display *p, int bottom_only)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- int sx, sy;
- u32 c;
-
- DTRACE;
-
- sx = conp->vc_cols * fontwidth(p); /* right margin */
- sy = conp->vc_rows * fontheight(p); /* bottom margin */
- c = attr_bgcol_ec(p, conp);
- c |= c << 8;
- c |= c << 16;
-
- if (!bottom_only) { /* right margin top->bottom */
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3ForegroundColor, c);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset
- (p->var.xoffset +
- sx)) | (PM3RectanglePosition_YOffset(p->
- var.
- yoffset)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(p->var.xres - sx)) |
- (PM3Render2D_Height(p->var.yres)));
+ if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) {
+ DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock));
+ return -EINVAL;
}
- /* bottom margin left -> right */
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3ForegroundColor, c);
+ var->accel_flags = 0; /* Can't mmap if this is on */
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(p->var.xoffset)) |
- (PM3RectanglePosition_YOffset(p->var.yoffset + sy)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(p->var.xres)) |
- (PM3Render2D_Height(p->var.yres - sy)));
-
- pm3fb_wait_pm3(l_fb_info);
-}
-#endif /* FBCON_HAS_CFB8 */
-#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
-static void pm3fb_cfbX_bmove(struct display *p,
- int sy, int sx,
- int dy, int dx, int height, int width)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- int x_align, o_x, o_y;
-
- DTRACE;
-
- sx = sx * fontwidth(p);
- dx = dx * fontwidth(p);
- width = width * fontwidth(p);
- sy = sy * fontheight(p);
- dy = dy * fontheight(p);
- height = height * fontheight(p);
-
- o_x = sx - dx; /*(sx > dx ) ? (sx - dx) : (dx - sx); */
- o_y = sy - dy; /*(sy > dy ) ? (sy - dy) : (dy - sy); */
-
- x_align = (sx & 0x1f);
-
- PM3_WAIT(6);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UserScissorEnable |
- PM3Config2D_ForegroundROPEnable |
- PM3Config2D_Blocking |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3ScissorMinXY,
- ((dy & 0x0fff) << 16) | (dx & 0x0fff));
- PM3_WRITE_REG(PM3ScissorMaxXY,
- (((dy + height) & 0x0fff) << 16) |
- ((dx + width) & 0x0fff));
-
- PM3_WRITE_REG(PM3FBSourceReadBufferOffset,
- PM3FBSourceReadBufferOffset_XOffset(o_x) |
- PM3FBSourceReadBufferOffset_YOffset(o_y));
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(dx - x_align)) |
- (PM3RectanglePosition_YOffset(dy)));
-
- PM3_WRITE_REG(PM3Render2D,
- ((sx > dx) ? PM3Render2D_XPositive : 0) |
- ((sy > dy) ? PM3Render2D_YPositive : 0) |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- PM3Render2D_FBSourceReadEnable |
- (PM3Render2D_Width(width + x_align)) |
- (PM3Render2D_Height(height)));
-
- pm3fb_wait_pm3(l_fb_info);
+ DPRINTK("Checking graphics mode at %dx%d depth %d\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ return 0;
}
-static void pm3fb_cfbX_putc(struct vc_data *conp, struct display *p,
- int c, int yy, int xx)
+static int pm3fb_set_par(struct fb_info *info)
{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- u8 *cdat, asx = 0, asy = 0, o_x = 0, o_y = 0;
- u32 fgx, bgx, ldat;
- int sx, sy, i;
-
- DTRACE;
-
- if (l_fb_info->current_par->depth == 8)
- fgx = attr_fgcol(p, c);
- else if (depth2bpp(l_fb_info->current_par->depth) == 16)
- fgx = ((u16 *) p->dispsw_data)[attr_fgcol(p, c)];
- else
- fgx = ((u32 *) p->dispsw_data)[attr_fgcol(p, c)];
-
- PM3_COLOR(fgx);
-
- if (l_fb_info->current_par->depth == 8)
- bgx = attr_bgcol(p, c);
- else if (depth2bpp(l_fb_info->current_par->depth) == 16)
- bgx = ((u16 *) p->dispsw_data)[attr_bgcol(p, c)];
- else
- bgx = ((u32 *) p->dispsw_data)[attr_bgcol(p, c)];
-
- PM3_COLOR(bgx);
-
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable | PM3Config2D_OpaqueSpan);
-
- PM3_WRITE_REG(PM3ForegroundColor, fgx);
- PM3_WRITE_REG(PM3FillBackgroundColor, bgx);
-
- /* WARNING : address select X need to specify 8 bits for fontwidth <= 8 */
- /* and 16 bits for fontwidth <= 16 */
- /* same in _putcs, same for Y and fontheight */
- if (fontwidth(p) <= 8)
- asx = 2;
- else if (fontwidth(p) <= 16)
- asx = 3; /* look OK */
- if (fontheight(p) <= 8)
- asy = 2;
- else if (fontheight(p) <= 16)
- asy = 3; /* look OK */
- else if (fontheight(p) <= 32)
- asy = 4; /* look OK */
-
- sx = xx * fontwidth(p);
- sy = yy * fontheight(p);
-
- if (fontwidth(p) <= 8)
- o_x = (8 - (sx & 0x7)) & 0x7;
- else if (fontwidth(p) <= 16)
- o_x = (16 - (sx & 0xF)) & 0xF;
- if (fontheight(p) <= 8)
- o_y = (8 - (sy & 0x7)) & 0x7;
- else if (fontheight(p) <= 16)
- o_y = (16 - (sy & 0xF)) & 0xF;
- else if (fontheight(p) <= 32)
- o_y = (32 - (sy & 0x1F)) & 0x1F;
-
- PM3_WRITE_REG(PM3AreaStippleMode, (o_x << 7) | (o_y << 12) | /* x_offset, y_offset in pattern */
- (1 << 18) | /* BE */
- 1 | (asx << 1) | (asy << 4) | /* address select x/y */
- (1 << 20)); /* OpaqueSpan */
-
- if (fontwidth(p) <= 8) {
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- } else {
- cdat =
- p->fontdata +
- ((c & p->charmask) * (fontheight(p) << 1));
- }
-
- PM3_WAIT(2 + fontheight(p));
-
- for (i = 0; i < fontheight(p); i++) { /* assume fontheight <= 32 */
- if (fontwidth(p) <= 8) {
- ldat = *cdat++;
- } else { /* assume fontwidth <= 16 ATM */
-
- ldat = ((*cdat++) << 8);
- ldat |= *cdat++;
- }
- PM3_WRITE_REG(AreaStipplePattern_indexed(i), ldat);
- }
+ struct pm3_par *par = info->par;
+ const u32 xres = (info->var.xres + 31) & ~31;
+ const int depth = (info->var.bits_per_pixel + 7) & ~7;
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(sx)) |
- (PM3RectanglePosition_YOffset(sy)));
+ par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
+ (info->var.yoffset * xres)
+ + info->var.xoffset);
+ par->video = 0;
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_AreaStippleEnable |
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(fontwidth(p))) |
- (PM3Render2D_Height(fontheight(p))));
-
- pm3fb_wait_pm3(l_fb_info);
-}
-
-static void pm3fb_cfbX_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy,
- int xx)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
- u8 *cdat, asx = 0, asy = 0, o_x = 0, o_y = 0;
- u32 fgx, bgx, ldat;
- int sx, sy, i, j;
- u16 sc;
-
- DTRACE;
-
- sc = scr_readw(s);
- if (l_fb_info->current_par->depth == 8)
- fgx = attr_fgcol(p, sc);
- else if (depth2bpp(l_fb_info->current_par->depth) == 16)
- fgx = ((u16 *) p->dispsw_data)[attr_fgcol(p, sc)];
- else
- fgx = ((u32 *) p->dispsw_data)[attr_fgcol(p, sc)];
-
- PM3_COLOR(fgx);
-
- if (l_fb_info->current_par->depth == 8)
- bgx = attr_bgcol(p, sc);
- else if (depth2bpp(l_fb_info->current_par->depth) == 16)
- bgx = ((u16 *) p->dispsw_data)[attr_bgcol(p, sc)];
+ if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ par->video |= PM3VideoControl_HSYNC_ACTIVE_HIGH;
else
- bgx = ((u32 *) p->dispsw_data)[attr_bgcol(p, sc)];
-
- PM3_COLOR(bgx);
-
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable |
- PM3Config2D_OpaqueSpan);
-
- PM3_WRITE_REG(PM3ForegroundColor, fgx);
- PM3_WRITE_REG(PM3FillBackgroundColor, bgx);
-
- /* WARNING : address select X need to specify 8 bits for fontwidth <= 8 */
- /* and 16 bits for fontwidth <= 16 */
- /* same in _putc, same for Y and fontheight */
- if (fontwidth(p) <= 8)
- asx = 2;
- else if (fontwidth(p) <= 16)
- asx = 3; /* look OK */
- if (fontheight(p) <= 8)
- asy = 2;
- else if (fontheight(p) <= 16)
- asy = 3; /* look OK */
- else if (fontheight(p) <= 32)
- asy = 4; /* look OK */
-
- sy = yy * fontheight(p);
-
- if (fontheight(p) <= 8)
- o_y = (8 - (sy & 0x7)) & 0x7;
- else if (fontheight(p) <= 16)
- o_y = (16 - (sy & 0xF)) & 0xF;
- else if (fontheight(p) <= 32)
- o_y = (32 - (sy & 0x1F)) & 0x1F;
-
- for (j = 0; j < count; j++) {
- sc = scr_readw(s + j);
- if (fontwidth(p) <= 8)
- cdat = p->fontdata +
- (sc & p->charmask) * fontheight(p);
- else
- cdat = p->fontdata +
- ((sc & p->charmask) * fontheight(p) << 1);
-
- sx = (xx + j) * fontwidth(p);
-
- if (fontwidth(p) <= 8)
- o_x = (8 - (sx & 0x7)) & 0x7;
- else if (fontwidth(p) <= 16)
- o_x = (16 - (sx & 0xF)) & 0xF;
-
- PM3_WAIT(3 + fontheight(p));
-
- PM3_WRITE_REG(PM3AreaStippleMode, (o_x << 7) | (o_y << 12) | /* x_offset, y_offset in pattern */
- (1 << 18) | /* BE */
- 1 | (asx << 1) | (asy << 4) | /* address select x/y */
- (1 << 20)); /* OpaqueSpan */
-
- for (i = 0; i < fontheight(p); i++) { /* assume fontheight <= 32 */
- if (fontwidth(p) <= 8) {
- ldat = *cdat++;
- } else { /* assume fontwidth <= 16 ATM */
- ldat = ((*cdat++) << 8);
- ldat |= *cdat++;
- }
- PM3_WRITE_REG(AreaStipplePattern_indexed(i), ldat);
- }
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(sx)) |
- (PM3RectanglePosition_YOffset(sy)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_AreaStippleEnable |
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(fontwidth(p))) |
- (PM3Render2D_Height(fontheight(p))));
- }
- pm3fb_wait_pm3(l_fb_info);
-}
-
-static void pm3fb_cfbX_revc(struct display *p, int xx, int yy)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
-
- xx = xx * fontwidth(p);
- yy = yy * fontheight(p);
-
- if (l_fb_info->current_par->depth == 8)
- {
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0x0F0F0F0F);
- else
- PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0x0F0F0F0F);
- }
-
- PM3_WAIT(3);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0xa)) | /* Oxa is GXinvert */
- PM3Config2D_FBDestReadEnable |
- PM3Config2D_FBWriteEnable);
-
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(xx)) |
- (PM3RectanglePosition_YOffset(yy)));
-
- PM3_WRITE_REG(PM3Render2D,
- PM3Render2D_XPositive |
- PM3Render2D_YPositive |
- PM3Render2D_Operation_Normal |
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(fontwidth(p))) |
- (PM3Render2D_Height(fontheight(p))));
-
- pm3fb_wait_pm3(l_fb_info);
-
- if (l_fb_info->current_par->depth == 8)
- {
- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
- PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0xFFFFFFFF);
- else
- PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xFFFFFFFF);
- }
-}
-
-#endif /* FBCON_HAS_CFB8 || FBCON_HAS_CFB16 || FBCON_HAS_CFB32 */
-#endif /* PM3FB_USE_ACCEL */
-/* *********************************** */
-/* ***** pre-init board(s) setup ***** */
-/* *********************************** */
-
-static void pm3fb_mode_setup(char *mode, unsigned long board_num)
-{
- struct pm3fb_info *l_fb_info = &(fb_info[board_num]);
- struct pm3fb_par *l_fb_par = &(current_par[board_num]);
- unsigned long i = 0;
-
- current_par_valid[board_num] = 0;
-
- if (!strncmp(mode, "current", 7)) {
- l_fb_info->use_current = 1; /* default w/ OpenFirmware */
- } else {
- while ((mode_base[i].name[0])
- && (!current_par_valid[board_num])) {
- if (!
- (strncmp
- (mode, mode_base[i].name,
- strlen(mode_base[i].name)))) {
- memcpy(l_fb_par, &(mode_base[i].user_mode),
- sizeof(struct pm3fb_par));
- current_par_valid[board_num] = 1;
- DPRINTK(2, "Mode set to %s\n",
- mode_base[i].name);
- }
- i++;
- }
- DASSERT(current_par_valid[board_num],
- "Valid mode on command line\n");
- }
-}
-
-static void pm3fb_pciid_setup(char *pciid, unsigned long board_num)
-{
- short l_bus = -1, l_slot = -1, l_func = -1;
- char *next;
-
- if (pciid) {
- l_bus = simple_strtoul(pciid, &next, 10);
- if (next && (next[0] == ':')) {
- pciid = next + 1;
- l_slot = simple_strtoul(pciid, &next, 10);
- if (next && (next[0] == ':')) {
- pciid = next + 1;
- l_func =
- simple_strtoul(pciid, (char **) NULL,
- 10);
- }
- }
- } else
- return;
-
- if ((l_bus >= 0) && (l_slot >= 0) && (l_func >= 0)) {
- bus[board_num] = l_bus;
- slot[board_num] = l_slot;
- func[board_num] = l_func;
- DPRINTK(2, "Board #%ld will be PciId: %hd:%hd:%hd\n",
- board_num, l_bus, l_slot, l_func);
- } else {
- DPRINTK(1, "Invalid PciId: %hd:%hd:%hd for board #%ld\n",
- l_bus, l_slot, l_func, board_num);
- }
-}
-
-static void pm3fb_font_setup(char *lf, unsigned long board_num)
-{
- unsigned long lfs = strlen(lf);
-
- if (lfs > (PM3_FONTNAME_SIZE - 1)) {
- DPRINTK(1, "Fontname %s too long\n", lf);
- return;
- }
- strlcpy(fontn[board_num], lf, lfs + 1);
-}
-
-static void pm3fb_bootdepth_setup(char *bds, unsigned long board_num)
-{
- unsigned long bd = simple_strtoul(bds, (char **) NULL, 10);
-
- if (!(depth_supported(bd))) {
- printk(KERN_WARNING "pm3fb: ignoring invalid depth %s for board #%ld\n",
- bds, board_num);
- return;
- }
- depth[board_num] = bd;
-}
-
-static void pm3fb_forcesize_setup(char *bds, unsigned long board_num)
-{
- unsigned long bd = simple_strtoul(bds, (char **) NULL, 10);
-
- if (bd > 64) {
- printk(KERN_WARNING "pm3fb: ignoring invalid memory size %s for board #%ld\n",
- bds, board_num);
- return;
- }
- forcesize[board_num] = bd;
-}
-
-static char *pm3fb_boardnum_setup(char *options, unsigned long *bn)
-{
- char *next;
-
- if (!(isdigit(options[0]))) {
- (*bn) = 0;
- return (options);
- }
-
- (*bn) = simple_strtoul(options, &next, 10);
+ par->video |= PM3VideoControl_HSYNC_ACTIVE_LOW;
- if (next && (next[0] == ':') && ((*bn) >= 0)
- && ((*bn) <= PM3_MAX_BOARD)) {
- DPRINTK(2, "Board_num seen as %ld\n", (*bn));
- return (next + 1);
- } else {
- (*bn) = 0;
- DPRINTK(2, "Board_num default to %ld\n", (*bn));
- return (options);
- }
-}
-
-static void pm3fb_real_setup(char *options)
-{
- char *next;
- unsigned long i, bn;
- struct pm3fb_info *l_fb_info;
-
- DTRACE;
-
- DPRINTK(2, "Options : %s\n", options);
-
- for (i = 0; i < PM3_MAX_BOARD; i++) {
- l_fb_info = &(fb_info[i]);
- memset(l_fb_info, 0, sizeof(struct pm3fb_info));
- l_fb_info->gen.fbhw = &pm3fb_switch;
- l_fb_info->board_num = i;
- current_par_valid[i] = 0;
- slot[i] = -1;
- func[i] = -1;
- bus[i] = -1;
- disable[i] = 0;
- noaccel[i] = 0;
- fontn[i][0] = '\0';
- depth[i] = 0;
- l_fb_info->current_par = &(current_par[i]);
- }
-
- /* eat up prefix pm3fb and whatever is used as separator i.e. :,= */
- if (!strncmp(options, "pm3fb", 5)) {
- options += 5;
- while (((*options) == ',') || ((*options) == ':')
- || ((*options) == '='))
- options++;
- }
-
- while (options) {
- bn = 0;
- if ((next = strchr(options, ','))) {
- (*next) = '\0';
- next++;
- }
-
- if (!strncmp(options, "mode:", 5)) {
- options = pm3fb_boardnum_setup(options + 5, &bn);
- DPRINTK(2, "Setting mode for board #%ld\n", bn);
- pm3fb_mode_setup(options, bn);
- } else if (!strncmp(options, "off:", 4)) {
- options = pm3fb_boardnum_setup(options + 4, &bn);
- DPRINTK(2, "Disabling board #%ld\n", bn);
- disable[bn] = 1;
- } else if (!strncmp(options, "off", 3)) { /* disable everything */
- for (i = 0; i < PM3_MAX_BOARD; i++)
- disable[i] = 1;
- } else if (!strncmp(options, "disable:", 8)) {
- options = pm3fb_boardnum_setup(options + 8, &bn);
- DPRINTK(2, "Disabling board #%ld\n", bn);
- disable[bn] = 1;
- } else if (!strncmp(options, "pciid:", 6)) {
- options = pm3fb_boardnum_setup(options + 6, &bn);
- DPRINTK(2, "Setting PciID for board #%ld\n", bn);
- pm3fb_pciid_setup(options, bn);
- } else if (!strncmp(options, "noaccel:", 8)) {
- options = pm3fb_boardnum_setup(options + 8, &bn);
- noaccel[bn] = 1;
- } else if (!strncmp(options, "font:", 5)) {
- options = pm3fb_boardnum_setup(options + 5, &bn);
- pm3fb_font_setup(options, bn);
- } else if (!strncmp(options, "depth:", 6)) {
- options = pm3fb_boardnum_setup(options + 6, &bn);
- pm3fb_bootdepth_setup(options, bn);
- } else if (!strncmp(options, "printtimings", 12)) {
- printtimings = 1;
- } else if (!strncmp(options, "flatpanel:", 10)) {
- options = pm3fb_boardnum_setup(options + 10, &bn);
- flatpanel[bn] = 1;
- } else if (!strncmp(options, "forcesize:", 10)) {
- options = pm3fb_boardnum_setup(options + 10, &bn);
- pm3fb_forcesize_setup(options, bn);
- }
- options = next;
- }
-}
-
-/* ********************************************** */
-/* ***** framebuffer API standard functions ***** */
-/* ********************************************** */
-
-static int pm3fb_encode_fix(struct fb_fix_screeninfo *fix,
- const void *par, struct fb_info_gen *info)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
- struct pm3fb_par *p = (struct pm3fb_par *) par;
-
- DTRACE;
-
- strcpy(fix->id, permedia3_name);
- fix->smem_start = (unsigned long)l_fb_info->p_fb;
- fix->smem_len = l_fb_info->fb_size;
- fix->mmio_start = (unsigned long)l_fb_info->pIOBase;
- fix->mmio_len = PM3_REGS_SIZE;
-#ifdef PM3FB_USE_ACCEL
- if (!(noaccel[l_fb_info->board_num]))
- fix->accel = FB_ACCEL_3DLABS_PERMEDIA3;
- else
-#endif /* PM3FB_USE_ACCEL */
- fix->accel = FB_ACCEL_NONE;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->visual =
- (p->depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- if (current_par_valid[l_fb_info->board_num])
- fix->line_length =
- l_fb_info->current_par->width *
- depth2ByPP(l_fb_info->current_par->depth);
+ if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ par->video |= PM3VideoControl_VSYNC_ACTIVE_HIGH;
else
- fix->line_length = 0;
- fix->xpanstep = 64 / depth2bpp(p->depth);
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
- return (0);
-}
-
-static int pm3fb_decode_var(const struct fb_var_screeninfo *var,
- void *par, struct fb_info_gen *info)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
- struct pm3fb_par *p = (struct pm3fb_par *) par;
- struct pm3fb_par temp_p;
- u32 xres;
-
- DTRACE;
-
- DASSERT((var != NULL), "fb_var_screeninfo* not NULL");
- DASSERT((p != NULL), "pm3fb_par* not NULL");
- DASSERT((l_fb_info != NULL), "pm3fb_info* not NULL");
+ par->video |= PM3VideoControl_VSYNC_ACTIVE_LOW;
- memset(&temp_p, 0, sizeof(struct pm3fb_par));
- temp_p.width = (var->xres_virtual + 7) & ~7;
- temp_p.height = var->yres_virtual;
-
- if (!(depth_supported(var->bits_per_pixel))) /* round unsupported up to a multiple of 8 */
- temp_p.depth = depth2bpp(var->bits_per_pixel);
+ if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
+ par->video |= PM3VideoControl_LINE_DOUBLE_ON;
else
- temp_p.depth = var->bits_per_pixel;
-
- temp_p.depth = (temp_p.depth > 32) ? 32 : temp_p.depth; /* max 32 */
- temp_p.depth = (temp_p.depth == 24) ? 32 : temp_p.depth; /* 24 unsupported, round-up to 32 */
-
- if ((temp_p.depth == 16) && (var->red.length == 5) && (var->green.length == 5) && (var->blue.length == 5))
- temp_p.depth = 15; /* RGBA 5551 is stored as depth 15 */
-
- if ((temp_p.depth == 16) && (var->red.length == 4) && (var->green.length == 4) && (var->blue.length == 4))
- temp_p.depth = 12; /* RGBA 4444 is stored as depth 12 */
-
-
- DPRINTK(2,
- "xres: %d, yres: %d, vxres: %d, vyres: %d ; xoffset:%d, yoffset: %d\n",
- var->xres, var->yres, var->xres_virtual, var->yres_virtual,
- var->xoffset, var->yoffset);
-
- xres = (var->xres + 31) & ~31;
- if (temp_p.width < xres + var->xoffset)
- temp_p.width = xres + var->xoffset;
- if (temp_p.height < var->yres + var->yoffset)
- temp_p.height = var->yres + var->yoffset;
-
- if (temp_p.width > 2048) {
- DPRINTK(1, "virtual width not supported: %u\n",
- temp_p.width);
- return (-EINVAL);
- }
- if (var->yres < 200) {
- DPRINTK(1, "height not supported: %u\n", (u32) var->yres);
- return (-EINVAL);
- }
- if (temp_p.height < 200 || temp_p.height > 4095) {
- DPRINTK(1, "virtual height not supported: %u\n",
- temp_p.height);
- return (-EINVAL);
- }
- if (!(depth_supported(temp_p.depth))) {
- DPRINTK(1, "depth not supported: %u\n", temp_p.depth);
- return (-EINVAL);
- }
- if ((temp_p.width * temp_p.height * depth2ByPP(temp_p.depth)) >
- l_fb_info->fb_size) {
- DPRINTK(1, "no memory for screen (%ux%ux%u)\n",
- temp_p.width, temp_p.height, temp_p.depth);
- return (-EINVAL);
- }
-
- if ((!var->pixclock) ||
- (!var->right_margin) ||
- (!var->hsync_len) ||
- (!var->left_margin) ||
- (!var->lower_margin) ||
- (!var->vsync_len) || (!var->upper_margin)
- ) {
- unsigned long i = 0, done = 0;
- printk(KERN_WARNING "pm3fb: refusing to use a likely wrong timing\n");
-
- while ((mode_base[i].user_mode.width) && !done) {
- if ((mode_base[i].user_mode.width == temp_p.width)
- && (mode_base[i].user_mode.height ==
- temp_p.height)) {
- printk(KERN_NOTICE "pm3fb: using close match %s\n",
- mode_base[i].name);
- temp_p = mode_base[i].user_mode;
- done = 1;
- }
- i++;
- }
- if (!done)
- return (-EINVAL);
- } else {
- temp_p.pixclock = PICOS2KHZ(var->pixclock);
- if (temp_p.pixclock > PM3_MAX_PIXCLOCK) {
- DPRINTK(1, "pixclock too high (%uKHz)\n",
- temp_p.pixclock);
- return (-EINVAL);
- }
-
- temp_p.hsstart = var->right_margin;
- temp_p.hsend = var->right_margin + var->hsync_len;
- temp_p.hbend =
- var->right_margin + var->hsync_len + var->left_margin;
- temp_p.htotal = xres + temp_p.hbend;
-
- temp_p.vsstart = var->lower_margin;
- temp_p.vsend = var->lower_margin + var->vsync_len;
- temp_p.vbend =
- var->lower_margin + var->vsync_len + var->upper_margin;
- temp_p.vtotal = var->yres + temp_p.vbend;
-
- temp_p.stride = temp_p.width;
-
- DPRINTK(2, "Using %d * %d, %d Khz, stride is %08x\n",
- temp_p.width, temp_p.height, temp_p.pixclock,
- temp_p.stride);
-
- temp_p.base =
- pm3fb_Shiftbpp(l_fb_info, temp_p.depth,
- (var->yoffset * xres) + var->xoffset);
+ par->video |= PM3VideoControl_LINE_DOUBLE_OFF;
- temp_p.video = 0;
-
- if (var->sync & FB_SYNC_HOR_HIGH_ACT)
- temp_p.video |= PM3VideoControl_HSYNC_ACTIVE_HIGH;
- else
- temp_p.video |= PM3VideoControl_HSYNC_ACTIVE_LOW;
-
- if (var->sync & FB_SYNC_VERT_HIGH_ACT)
- temp_p.video |= PM3VideoControl_VSYNC_ACTIVE_HIGH;
- else
- temp_p.video |= PM3VideoControl_VSYNC_ACTIVE_LOW;
-
- if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
- DPRINTK(1, "Interlaced mode not supported\n\n");
- return (-EINVAL);
- }
-
- if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
- temp_p.video |= PM3VideoControl_LINE_DOUBLE_ON;
- else
- temp_p.video |= PM3VideoControl_LINE_DOUBLE_OFF;
-
- if (var->activate == FB_ACTIVATE_NOW)
- temp_p.video |= PM3VideoControl_ENABLE;
- else {
- temp_p.video |= PM3VideoControl_DISABLE;
- DPRINTK(2, "PM3Video disabled\n");
- }
-
- switch (temp_p.depth) {
- case 8:
- temp_p.video |= PM3VideoControl_PIXELSIZE_8BIT;
- break;
- case 12:
- case 15:
- case 16:
- temp_p.video |= PM3VideoControl_PIXELSIZE_16BIT;
- break;
- case 32:
- temp_p.video |= PM3VideoControl_PIXELSIZE_32BIT;
- break;
- default:
- DPRINTK(1, "Unsupported depth\n");
- break;
- }
+ if (info->var.activate == FB_ACTIVATE_NOW)
+ par->video |= PM3VideoControl_ENABLE;
+ else {
+ par->video |= PM3VideoControl_DISABLE;
+ DPRINTK("PM3Video disabled\n");
}
- (*p) = temp_p;
-
-#ifdef PM3FB_USE_ACCEL
- if (var->accel_flags & FB_ACCELF_TEXT)
- noaccel[l_fb_info->board_num] = 0;
- else
- noaccel[l_fb_info->board_num] = 1;
-#endif /* PM3FB_USE_ACCEL */
-
- return (0);
-}
-
-static void pm3fb_encode_depth(struct fb_var_screeninfo *var, long d)
-{
- switch (d) {
+ switch (depth) {
case 8:
- var->red.length = var->green.length = var->blue.length = 8;
- var->red.offset = var->green.offset = var->blue.offset = 0;
- var->transp.offset = var->transp.length = 0;
+ par->video |= PM3VideoControl_PIXELSIZE_8BIT;
break;
-
case 12:
- var->red.offset = 8;
- var->red.length = 4;
- var->green.offset = 4;
- var->green.length = 4;
- var->blue.offset = 0;
- var->blue.length = 4;
- var->transp.offset = 12;
- var->transp.length = 4;
- break;
-
case 15:
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 15;
- var->transp.length = 1;
- break;
-
case 16:
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = var->transp.length = 0;
+ par->video |= PM3VideoControl_PIXELSIZE_16BIT;
break;
-
case 32:
- var->transp.offset = 24;
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->red.length = var->green.length =
- var->blue.length = var->transp.length = 8;
+ par->video |= PM3VideoControl_PIXELSIZE_32BIT;
break;
-
default:
- DPRINTK(1, "Unsupported depth %ld\n", d);
+ DPRINTK("Unsupported depth\n");
break;
}
-}
-
-static int pm3fb_encode_var(struct fb_var_screeninfo *var,
- const void *par, struct fb_info_gen *info)
-{
- struct pm3fb_par *p = (struct pm3fb_par *) par;
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
-
- u32 base;
-
- DTRACE;
-
- DASSERT((var != NULL), "fb_var_screeninfo* not NULL");
- DASSERT((p != NULL), "pm3fb_par* not NULL");
- DASSERT((info != NULL), "fb_info_gen* not NULL");
-
- memset(var, 0, sizeof(struct fb_var_screeninfo));
-
-#ifdef PM3FB_USE_ACCEL
- if (!(noaccel[l_fb_info->board_num]))
- var->accel_flags |= FB_ACCELF_TEXT;
-#endif /* PM3FB_USE_ACCEL */
-
- var->xres_virtual = p->width;
- var->yres_virtual = p->height;
- var->xres = p->htotal - p->hbend;
- var->yres = p->vtotal - p->vbend;
-
- DPRINTK(2, "xres = %d, yres : %d\n", var->xres, var->yres);
-
- var->right_margin = p->hsstart;
- var->hsync_len = p->hsend - p->hsstart;
- var->left_margin = p->hbend - p->hsend;
- var->lower_margin = p->vsstart;
- var->vsync_len = p->vsend - p->vsstart;
- var->upper_margin = p->vbend - p->vsend;
- var->bits_per_pixel = depth2bpp(p->depth);
-
- pm3fb_encode_depth(var, p->depth);
-
- base = pm3fb_Unshiftbpp(l_fb_info, p->depth, p->base);
-
- var->xoffset = base % var->xres;
- var->yoffset = base / var->xres;
-
- var->height = var->width = -1;
-
- var->pixclock = KHZ2PICOS(p->pixclock);
-
- if ((p->video & PM3VideoControl_HSYNC_MASK) ==
- PM3VideoControl_HSYNC_ACTIVE_HIGH)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if ((p->video & PM3VideoControl_VSYNC_MASK) ==
- PM3VideoControl_VSYNC_ACTIVE_HIGH)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- if (p->video & PM3VideoControl_LINE_DOUBLE_ON)
- var->vmode = FB_VMODE_DOUBLE;
-
- return (0);
-}
-
-static void pm3fb_get_par(void *par, struct fb_info_gen *info)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
-
- DTRACE;
-
- if (!current_par_valid[l_fb_info->board_num]) {
- if (l_fb_info->use_current)
- pm3fb_read_mode(l_fb_info, l_fb_info->current_par);
- else
- memcpy(l_fb_info->current_par,
- &(mode_base[0].user_mode),
- sizeof(struct pm3fb_par));
- current_par_valid[l_fb_info->board_num] = 1;
- }
- *((struct pm3fb_par *) par) = *(l_fb_info->current_par);
-}
-
-static void pm3fb_set_par(const void *par, struct fb_info_gen *info)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
-
- DTRACE;
- *(l_fb_info->current_par) = *((struct pm3fb_par *) par);
- current_par_valid[l_fb_info->board_num] = 1;
+ info->fix.visual =
+ (depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = ((info->var.xres_virtual + 7) & ~7)
+ * depth / 8;
- pm3fb_write_mode(l_fb_info);
-
-#ifdef PM3FB_USE_ACCEL
- pm3fb_init_engine(l_fb_info);
-#endif /* PM3FB_USE_ACCEL */
-}
-
-static void pm3fb_set_color(struct pm3fb_info *l_fb_info,
- unsigned char regno, unsigned char r,
- unsigned char g, unsigned char b)
-{
- DTRACE;
-
- PM3_SLOW_WRITE_REG(PM3RD_PaletteWriteAddress, regno);
- PM3_SLOW_WRITE_REG(PM3RD_PaletteData, r);
- PM3_SLOW_WRITE_REG(PM3RD_PaletteData, g);
- PM3_SLOW_WRITE_REG(PM3RD_PaletteData, b);
-}
-
-static int pm3fb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
-
- DTRACE;
-
- if (regno < 256) {
- *red =
- l_fb_info->palette[regno].red << 8 | l_fb_info->
- palette[regno].red;
- *green =
- l_fb_info->palette[regno].green << 8 | l_fb_info->
- palette[regno].green;
- *blue =
- l_fb_info->palette[regno].blue << 8 | l_fb_info->
- palette[regno].blue;
- *transp =
- l_fb_info->palette[regno].transp << 8 | l_fb_info->
- palette[regno].transp;
- }
- return (regno > 255);
+/* pm3fb_clear_memory(info, 0);*/
+ pm3fb_clear_colormap(par, 0, 0, 0);
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorMode,
+ PM3RD_CursorMode_CURSOR_DISABLE);
+ pm3fb_write_mode(info);
+ return 0;
}
static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info)
{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
-
- DTRACE;
+ struct pm3_par *par = info->par;
+
+ if (regno >= 256) /* no. of hw registers */
+ return -EINVAL;
+
+ /* grayscale works only partially under directcolor */
+ if (info->var.grayscale) {
+ /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+ }
+
+ /* Directcolor:
+ * var->{color}.offset contains start of bitfield
+ * var->{color}.length contains length of bitfield
+ * {hardwarespecific} contains width of DAC
+ * pseudo_palette[X] is programmed to (X << red.offset) |
+ * (X << green.offset) |
+ * (X << blue.offset)
+ * RAMDAC[X] is programmed to (red, green, blue)
+ * color depth = SUM(var->{color}.length)
+ *
+ * Pseudocolor:
+ * var->{color}.offset is 0
+ * var->{color}.length contains width of DAC or the number of unique
+ * colors available (color depth)
+ * pseudo_palette is not used
+ * RAMDAC[X] is programmed to (red, green, blue)
+ * color depth = var->{color}.length
+ */
- if (regno < 16) {
- switch (l_fb_info->current_par->depth) {
-#ifdef FBCON_HAS_CFB8
+ /*
+ * This is the point where the color is converted to something that
+ * is acceptable by the hardware.
+ */
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+ red = CNVT_TOHW(red, info->var.red.length);
+ green = CNVT_TOHW(green, info->var.green.length);
+ blue = CNVT_TOHW(blue, info->var.blue.length);
+ transp = CNVT_TOHW(transp, info->var.transp.length);
+#undef CNVT_TOHW
+
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ u32 v;
+
+ if (regno >= 16)
+ return -EINVAL;
+
+ v = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset) |
+ (transp << info->var.transp.offset);
+
+ switch (info->var.bits_per_pixel) {
case 8:
break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 12:
- l_fb_info->cmap.cmap12[regno] =
- (((u32) red & 0xf000) >> 4) |
- (((u32) green & 0xf000) >> 8) |
- (((u32) blue & 0xf000) >> 12);
- break;
-
- case 15:
- l_fb_info->cmap.cmap15[regno] =
- (((u32) red & 0xf800) >> 1) |
- (((u32) green & 0xf800) >> 6) |
- (((u32) blue & 0xf800) >> 11);
- break;
-
case 16:
- l_fb_info->cmap.cmap16[regno] =
- ((u32) red & 0xf800) |
- (((u32) green & 0xfc00) >> 5) |
- (((u32) blue & 0xf800) >> 11);
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
+ case 24:
case 32:
- l_fb_info->cmap.cmap32[regno] =
- (((u32) transp & 0xff00) << 16) |
- (((u32) red & 0xff00) << 8) |
- (((u32) green & 0xff00)) |
- (((u32) blue & 0xff00) >> 8);
- break;
-#endif
- default:
- DPRINTK(1, "bad depth %u\n",
- l_fb_info->current_par->depth);
+ ((u32*)(info->pseudo_palette))[regno] = v;
break;
}
+ return 0;
}
- if (regno < 256) {
- l_fb_info->palette[regno].red = red >> 8;
- l_fb_info->palette[regno].green = green >> 8;
- l_fb_info->palette[regno].blue = blue >> 8;
- l_fb_info->palette[regno].transp = transp >> 8;
- if (l_fb_info->current_par->depth == 8)
- pm3fb_set_color(l_fb_info, regno, red >> 8,
- green >> 8, blue >> 8);
- }
- return (regno > 255);
+ else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
+ pm3fb_set_color(par, regno, red, green, blue);
+
+ return 0;
}
-static int pm3fb_blank(int blank_mode, struct fb_info_gen *info)
+static int pm3fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
- u32 video;
-
- DTRACE;
+ struct pm3_par *par = info->par;
+ const u32 xres = (var->xres + 31) & ~31;
- if (!current_par_valid[l_fb_info->board_num])
- return (1);
+ par->base = pm3fb_shift_bpp(var->bits_per_pixel,
+ (var->yoffset * xres)
+ + var->xoffset);
+ PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
+ return 0;
+}
- video = l_fb_info->current_par->video;
+static int pm3fb_blank(int blank_mode, struct fb_info *info)
+{
+ struct pm3_par *par = info->par;
+ u32 video = par->video;
/*
* Oxygen VX1 - it appears that setting PM3VideoControl and
@@ -3181,454 +663,345 @@ static int pm3fb_blank(int blank_mode, struct fb_info_gen *info)
video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
PM3VideoControl_VSYNC_ACTIVE_HIGH;
- if (blank_mode > 0) {
- switch (blank_mode - 1) {
-
- case VESA_NO_BLANKING: /* FIXME */
- video = video & ~(PM3VideoControl_ENABLE);
- break;
-
- case VESA_HSYNC_SUSPEND:
- video = video & ~(PM3VideoControl_HSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
- break;
- case VESA_VSYNC_SUSPEND:
- video = video & ~(PM3VideoControl_VSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
- break;
- case VESA_POWERDOWN:
- video = video & ~(PM3VideoControl_HSYNC_MASK |
- PM3VideoControl_VSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
- break;
- default:
- DPRINTK(1, "Unsupported blanking %d\n",
- blank_mode);
- return (1);
- break;
- }
- }
-
- PM3_SLOW_WRITE_REG(PM3VideoControl, video);
-
- return (0);
-}
-
-static void pm3fb_set_disp(const void *par, struct display *disp,
- struct fb_info_gen *info)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
- struct pm3fb_par *p = (struct pm3fb_par *) par;
- u32 flags;
-
- DTRACE;
-
- local_irq_save(flags);
- info->info.screen_base = l_fb_info->v_fb;
- switch (p->depth) {
-#ifdef FBCON_HAS_CFB8
- case 8:
-#ifdef PM3FB_USE_ACCEL
- if (!(noaccel[l_fb_info->board_num]))
- disp->dispsw = &pm3fb_cfb8;
- else
-#endif /* PM3FB_USE_ACCEL */
- disp->dispsw = &fbcon_cfb8;
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ video = video | PM3VideoControl_ENABLE;
break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 12:
-#ifdef PM3FB_USE_ACCEL
- if (!(noaccel[l_fb_info->board_num]))
- disp->dispsw = &pm3fb_cfb16;
- else
-#endif /* PM3FB_USE_ACCEL */
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = l_fb_info->cmap.cmap12;
+ case FB_BLANK_NORMAL: /* FIXME */
+ video = video & ~(PM3VideoControl_ENABLE);
break;
- case 15:
-#ifdef PM3FB_USE_ACCEL
- if (!(noaccel[l_fb_info->board_num]))
- disp->dispsw = &pm3fb_cfb16;
- else
-#endif /* PM3FB_USE_ACCEL */
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = l_fb_info->cmap.cmap15;
+ case FB_BLANK_HSYNC_SUSPEND:
+ video = video & ~(PM3VideoControl_HSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
- case 16:
-#ifdef PM3FB_USE_ACCEL
- if (!(noaccel[l_fb_info->board_num]))
- disp->dispsw = &pm3fb_cfb16;
- else
-#endif /* PM3FB_USE_ACCEL */
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = l_fb_info->cmap.cmap16;
+ case FB_BLANK_VSYNC_SUSPEND:
+ video = video & ~(PM3VideoControl_VSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
-#ifdef PM3FB_USE_ACCEL
- if (!(noaccel[l_fb_info->board_num]))
- disp->dispsw = &pm3fb_cfb32;
- else
-#endif /* PM3FB_USE_ACCEL */
- disp->dispsw = &fbcon_cfb32;
- disp->dispsw_data = l_fb_info->cmap.cmap32;
+ case FB_BLANK_POWERDOWN:
+ video = video & ~(PM3VideoControl_HSYNC_MASK |
+ PM3VideoControl_VSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
-#endif /* FBCON_HAS_CFB32 */
default:
- disp->dispsw = &fbcon_dummy;
- DPRINTK(1, "Invalid depth, using fbcon_dummy\n");
- break;
+ DPRINTK("Unsupported blanking %d\n", blank_mode);
+ return 1;
}
- local_irq_restore(flags);
+
+ PM3_SLOW_WRITE_REG(par,PM3VideoControl, video);
+
+ return 0;
}
-/* */
-static void pm3fb_detect(void)
-{
- struct pci_dev *dev_array[PM3_MAX_BOARD];
- struct pci_dev *dev = NULL;
- struct pm3fb_info *l_fb_info = &(fb_info[0]);
- unsigned long i, j, done;
+ /*
+ * Frame buffer operations
+ */
- DTRACE;
+static struct fb_ops pm3fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = pm3fb_check_var,
+ .fb_set_par = pm3fb_set_par,
+ .fb_setcolreg = pm3fb_setcolreg,
+ .fb_pan_display = pm3fb_pan_display,
+ .fb_fillrect = cfb_fillrect, /* Needed !!! */
+ .fb_copyarea = cfb_copyarea, /* Needed !!! */
+ .fb_imageblit = cfb_imageblit, /* Needed !!! */
+ .fb_blank = pm3fb_blank,
+};
- for (i = 0; i < PM3_MAX_BOARD; i++) {
- dev_array[i] = NULL;
- fb_info[i].dev = NULL;
- }
+/* ------------------------------------------------------------------------- */
- dev = pci_get_device(PCI_VENDOR_ID_3DLABS,
- PCI_DEVICE_ID_3DLABS_PERMEDIA3, dev);
+ /*
+ * Initialization
+ */
- for (i = 0; ((i < PM3_MAX_BOARD) && dev); i++) {
- dev_array[i] = dev;
- dev = pci_get_device(PCI_VENDOR_ID_3DLABS,
- PCI_DEVICE_ID_3DLABS_PERMEDIA3, dev);
- }
+/* mmio register are already mapped when this function is called */
+/* the pm3fb_fix.smem_start is also set */
+static unsigned long pm3fb_size_memory(struct pm3_par *par)
+{
+ unsigned long memsize = 0, tempBypass, i, temp1, temp2;
+ unsigned char __iomem *screen_mem;
- if (dev) { /* more than PM3_MAX_BOARD */
- printk(KERN_WARNING "pm3fb: Warning: more than %d boards found\n",
- PM3_MAX_BOARD);
+ pm3fb_fix.smem_len = 64 * 1024 * 1024; /* request full aperture size */
+ /* Linear frame buffer - request region and map it. */
+ if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
+ "pm3fb smem")) {
+ printk(KERN_WARNING "pm3fb: Can't reserve smem.\n");
+ return 0;
}
-
- if (!dev_array[0]) { /* not a single board, abort */
- return;
+ screen_mem =
+ ioremap_nocache(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
+ if (!screen_mem) {
+ printk(KERN_WARNING "pm3fb: Can't ioremap smem area.\n");
+ release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
+ return 0;
}
- /* allocate user-defined boards */
- for (i = 0; i < PM3_MAX_BOARD; i++) {
- if ((bus[i] >= 0) && (slot[i] >= 0) && (func[i] >= 0)) {
- for (j = 0; j < PM3_MAX_BOARD; j++) {
- if ((dev_array[j] != NULL) &&
- (dev_array[j]->bus->number == bus[i])
- && (PCI_SLOT(dev_array[j]->devfn) ==
- slot[i])
- && (PCI_FUNC(dev_array[j]->devfn) ==
- func[i])) {
- fb_info[i].dev = dev_array[j];
- dev_array[j] = NULL;
- }
- }
- }
+ /* TODO: card-specific stuff, *before* accessing *any* FB memory */
+ /* For Appian Jeronimo 2000 board second head */
+
+ tempBypass = PM3_READ_REG(par, PM3MemBypassWriteMask);
+
+ DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
+
+ PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
+
+ /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
+ for (i = 0; i < 32; i++) {
+ fb_writel(i * 0x00345678,
+ (screen_mem + (i * 1048576)));
+ mb();
+ temp1 = fb_readl((screen_mem + (i * 1048576)));
+
+ /* Let's check for wrapover, write will fail at 16MB boundary */
+ if (temp1 == (i * 0x00345678))
+ memsize = i;
+ else
+ break;
}
- /* allocate remaining boards */
- for (i = 0; i < PM3_MAX_BOARD; i++) {
- if (fb_info[i].dev == NULL) {
- done = 0;
- for (j = 0; ((j < PM3_MAX_BOARD) && (!done)); j++) {
- if (dev_array[j] != NULL) {
- fb_info[i].dev = dev_array[j];
- dev_array[j] = NULL;
- done = 1;
- }
- }
+
+ DPRINTK("First detect pass already got %ld MB\n", memsize + 1);
+
+ if (memsize + 1 == i) {
+ for (i = 0; i < 32; i++) {
+ /* Clear first 32MB ; 0 is 0, no need to byteswap */
+ writel(0x0000000,
+ (screen_mem + (i * 1048576)));
+ mb();
}
- }
- /* at that point, all PCI Permedia3 are detected and allocated */
- /* now, initialize... or not */
- for (i = 0; i < PM3_MAX_BOARD; i++) {
- l_fb_info = &(fb_info[i]);
- if (l_fb_info->dev && !disable[i]) { /* PCI device was found and not disabled by user */
- DPRINTK(2,
- "found @%lx Vendor %lx Device %lx ; base @ : %lx - %lx - %lx - %lx - %lx - %lx, irq %ld\n",
- (unsigned long) l_fb_info->dev,
- (unsigned long) l_fb_info->dev->vendor,
- (unsigned long) l_fb_info->dev->device,
- (unsigned long)
- pci_resource_start(l_fb_info->dev, 0),
- (unsigned long)
- pci_resource_start(l_fb_info->dev, 1),
- (unsigned long)
- pci_resource_start(l_fb_info->dev, 2),
- (unsigned long)
- pci_resource_start(l_fb_info->dev, 3),
- (unsigned long)
- pci_resource_start(l_fb_info->dev, 4),
- (unsigned long)
- pci_resource_start(l_fb_info->dev, 5),
- (unsigned long) l_fb_info->dev->irq);
-
- l_fb_info->pIOBase =
- (unsigned char *)
- pci_resource_start(l_fb_info->dev, 0);
-#ifdef __BIG_ENDIAN
- l_fb_info->pIOBase += PM3_REGS_SIZE;
-#endif
- l_fb_info->vIOBase = (unsigned char *) -1;
- l_fb_info->p_fb =
- (unsigned char *)
- pci_resource_start(l_fb_info->dev, 1);
- l_fb_info->v_fb = (unsigned char *) -1;
-
- if (!request_mem_region
- ((unsigned long)l_fb_info->p_fb, 64 * 1024 * 1024, /* request full aperture size */
- "pm3fb")) {
- printk
- (KERN_ERR "pm3fb: Error: couldn't request framebuffer memory, board #%ld\n",
- l_fb_info->board_num);
- continue;
- }
- if (!request_mem_region
- ((unsigned long)l_fb_info->pIOBase, PM3_REGS_SIZE,
- "pm3fb I/O regs")) {
- printk
- (KERN_ERR "pm3fb: Error: couldn't request IObase memory, board #%ld\n",
- l_fb_info->board_num);
- continue;
- }
- if (forcesize[l_fb_info->board_num])
- l_fb_info->fb_size = forcesize[l_fb_info->board_num];
-
- l_fb_info->fb_size =
- pm3fb_size_memory(l_fb_info);
- if (l_fb_info->fb_size) {
- (void) pci_enable_device(l_fb_info->dev);
- pm3fb_common_init(l_fb_info);
- } else
- printk(KERN_ERR "pm3fb: memory problem, not enabling board #%ld\n", l_fb_info->board_num);
+ for (i = 32; i < 64; i++) {
+ fb_writel(i * 0x00345678,
+ (screen_mem + (i * 1048576)));
+ mb();
+ temp1 =
+ fb_readl((screen_mem + (i * 1048576)));
+ temp2 =
+ fb_readl((screen_mem + ((i - 32) * 1048576)));
+ /* different value, different RAM... */
+ if ((temp1 == (i * 0x00345678)) && (temp2 == 0))
+ memsize = i;
+ else
+ break;
}
}
-}
+ DPRINTK("Second detect pass got %ld MB\n", memsize + 1);
-static int pm3fb_pan_display(const struct fb_var_screeninfo *var,
- struct fb_info_gen *info)
-{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
+ PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
- DTRACE;
+ iounmap(screen_mem);
+ release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
+ memsize = 1048576 * (memsize + 1);
- if (!current_par_valid[l_fb_info->board_num])
- return -EINVAL;
+ DPRINTK("Returning 0x%08lx bytes\n", memsize);
- l_fb_info->current_par->base = /* in 128 bits chunk - i.e. AFTER Shiftbpp */
- pm3fb_Shiftbpp(l_fb_info,
- l_fb_info->current_par->depth,
- (var->yoffset * l_fb_info->current_par->width) +
- var->xoffset);
- PM3_SLOW_WRITE_REG(PM3ScreenBase, l_fb_info->current_par->base);
- return 0;
+ return memsize;
}
-static int pm3fb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
+static int __devinit pm3fb_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
{
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) info;
- u32 cm, i;
-#ifdef PM3FB_MASTER_DEBUG
- char cc[3];
-#endif /* PM3FB_MASTER_DEBUG */
+ struct fb_info *info;
+ struct pm3_par *par;
+ struct device* device = &dev->dev; /* for pci drivers */
+ int err, retval = -ENXIO;
- switch(cmd)
- {
-#ifdef PM3FB_MASTER_DEBUG
- case PM3FBIO_CLEARMEMORY:
- if (copy_from_user(&cm, (void *)arg, sizeof(u32)))
- return(-EFAULT);
- pm3fb_clear_memory(l_fb_info, cm);
- return(0);
- break;
+ err = pci_enable_device(dev);
+ if (err) {
+ printk(KERN_WARNING "pm3fb: Can't enable PCI dev: %d\n", err);
+ return err;
+ }
+ /*
+ * Dynamically allocate info and par
+ */
+ info = framebuffer_alloc(sizeof(struct pm3_par), device);
- case PM3FBIO_CLEARCMAP:
- if (copy_from_user(cc, (void*)arg, 3 * sizeof(char)))
- return(-EFAULT);
- pm3fb_clear_colormap(l_fb_info, cc[0], cc[1], cc[2]);
- return(0);
- break;
-#endif /* PM3FB_MASTER_DEBUG */
-
- case PM3FBIO_RESETCHIP:
- cm = 1;
- PM3_SLOW_WRITE_REG(PM3ResetStatus, 1);
- for (i = 0 ; (i < 10000) && cm ; i++)
- {
- PM3_DELAY(10);
- cm = PM3_READ_REG(PM3ResetStatus);
- }
- if (cm)
- {
- printk(KERN_ERR "pm3fb: chip reset failed with status 0x%x\n", cm);
- return(-EIO);
- }
- /* first thing first, reload memory timings */
- pm3fb_write_memory_timings(l_fb_info);
-#ifdef PM3FB_USE_ACCEL
- pm3fb_init_engine(l_fb_info);
-#endif /* PM3FB_USE_ACCEL */
- pm3fb_write_mode(l_fb_info);
- return(0);
- break;
+ if (!info)
+ return -ENOMEM;
+ par = info->par;
- default:
- DPRINTK(2, "unknown ioctl: %d (%x)\n", cmd, cmd);
- return(-EINVAL);
+ /*
+ * Here we set the screen_base to the virtual memory address
+ * for the framebuffer.
+ */
+ pm3fb_fix.mmio_start = pci_resource_start(dev, 0);
+ pm3fb_fix.mmio_len = PM3_REGS_SIZE;
+
+ /* Registers - request region and map it. */
+ if (!request_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len,
+ "pm3fb regbase")) {
+ printk(KERN_WARNING "pm3fb: Can't reserve regbase.\n");
+ goto err_exit_neither;
+ }
+ par->v_regs =
+ ioremap_nocache(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len);
+ if (!par->v_regs) {
+ printk(KERN_WARNING "pm3fb: Can't remap %s register area.\n",
+ pm3fb_fix.id);
+ release_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len);
+ goto err_exit_neither;
+ }
+
+#if defined(__BIG_ENDIAN)
+ pm3fb_fix.mmio_start += PM3_REGS_SIZE;
+ DPRINTK("Adjusting register base for big-endian.\n");
+#endif
+ /* Linear frame buffer - request region and map it. */
+ pm3fb_fix.smem_start = pci_resource_start(dev, 1);
+ pm3fb_fix.smem_len = pm3fb_size_memory(par);
+ if (!pm3fb_fix.smem_len)
+ {
+ printk(KERN_WARNING "pm3fb: Can't find memory on board.\n");
+ goto err_exit_mmio;
}
-}
+ if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
+ "pm3fb smem")) {
+ printk(KERN_WARNING "pm3fb: Can't reserve smem.\n");
+ goto err_exit_mmio;
+ }
+ info->screen_base =
+ ioremap_nocache(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
+ if (!info->screen_base) {
+ printk(KERN_WARNING "pm3fb: Can't ioremap smem area.\n");
+ release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
+ goto err_exit_mmio;
+ }
+ info->screen_size = pm3fb_fix.smem_len;
-/* ****************************************** */
-/* ***** standard FB API init functions ***** */
-/* ****************************************** */
+ info->fbops = &pm3fb_ops;
-int __init pm3fb_setup(char *options)
-{
- long opsi = strlen(options);
+ par->video = PM3_READ_REG(par, PM3VideoControl);
- DTRACE;
+ info->fix = pm3fb_fix;
+ info->pseudo_palette = par->palette;
+ info->flags = FBINFO_DEFAULT;/* | FBINFO_HWACCEL_YPAN;*/
- memcpy(g_options, options,
- ((opsi + 1) >
- PM3_OPTIONS_SIZE) ? PM3_OPTIONS_SIZE : (opsi + 1));
- g_options[PM3_OPTIONS_SIZE - 1] = 0;
+ /*
+ * This should give a reasonable default video mode. The following is
+ * done when we can set a video mode.
+ */
+ if (!mode_option)
+ mode_option = "640x480@60";
+
+ retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
+
+ if (!retval || retval == 4) {
+ retval = -EINVAL;
+ goto err_exit_both;
+ }
+
+ /* This has to been done !!! */
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ retval = -ENOMEM;
+ goto err_exit_both;
+ }
- return (0);
+ /*
+ * For drivers that can...
+ */
+ pm3fb_check_var(&info->var, info);
+
+ if (register_framebuffer(info) < 0) {
+ retval = -EINVAL;
+ goto err_exit_all;
+ }
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+ info->fix.id);
+ pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */
+ return 0;
+
+ err_exit_all:
+ fb_dealloc_cmap(&info->cmap);
+ err_exit_both:
+ iounmap(info->screen_base);
+ release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
+ err_exit_mmio:
+ iounmap(par->v_regs);
+ release_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len);
+ err_exit_neither:
+ framebuffer_release(info);
+ return retval;
}
-int __init pm3fb_init(void)
+ /*
+ * Cleanup
+ */
+static void __devexit pm3fb_remove(struct pci_dev *dev)
{
- DTRACE;
+ struct fb_info *info = pci_get_drvdata(dev);
- DPRINTK(2, "This is pm3fb.c, CVS version: $Header: /cvsroot/linux/drivers/video/pm3fb.c,v 1.1 2002/02/25 19:11:06 marcelo Exp $");
+ if (info) {
+ struct fb_fix_screeninfo *fix = &info->fix;
+ struct pm3_par *par = info->par;
- pm3fb_real_setup(g_options);
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
- pm3fb_detect();
+ iounmap(info->screen_base);
+ release_mem_region(fix->smem_start, fix->smem_len);
+ iounmap(par->v_regs);
+ release_mem_region(fix->mmio_start, fix->mmio_len);
- if (!fb_info[0].dev) { /* not even one board ??? */
- DPRINTK(1, "No PCI Permedia3 board detected\n");
+ pci_set_drvdata(dev, NULL);
+ framebuffer_release(info);
}
- return (0);
}
-/* ************************* */
-/* **** Module support ***** */
-/* ************************* */
-
-#ifdef MODULE
-MODULE_AUTHOR("Romain Dolbeau");
-MODULE_DESCRIPTION("Permedia3 framebuffer device driver");
-static char *mode[PM3_MAX_BOARD];
-module_param_array(mode, charp, NULL, 0);
-MODULE_PARM_DESC(mode,"video mode");
-module_param_array(disable, short, NULL, 0);
-MODULE_PARM_DESC(disable,"disable board");
-static short off[PM3_MAX_BOARD];
-module_param_array(off, short, NULL, 0);
-MODULE_PARM_DESC(off,"disable board");
-static char *pciid[PM3_MAX_BOARD];
-module_param_array(pciid, charp, NULL, 0);
-MODULE_PARM_DESC(pciid,"board PCI Id");
-module_param_array(noaccel, short, NULL, 0);
-MODULE_PARM_DESC(noaccel,"disable accel");
-static char *font[PM3_MAX_BOARD];
-module_param_array(font, charp, NULL, 0);
-MODULE_PARM_DESC(font,"choose font");
-module_param(depth, short, NULL, 0);
-MODULE_PARM_DESC(depth,"boot-time depth");
-module_param(printtimings, short, NULL, 0);
-MODULE_PARM_DESC(printtimings, "print the memory timings of the card(s)");
-module_param(forcesize, short, NULL, 0);
-MODULE_PARM_DESC(forcesize, "force specified memory size");
-/*
-MODULE_SUPPORTED_DEVICE("Permedia3 PCI boards")
-MODULE_GENERIC_TABLE(gtype,name)
-MODULE_DEVICE_TABLE(type,name)
-*/
+static struct pci_device_id pm3fb_id_table[] = {
+ { PCI_VENDOR_ID_3DLABS, 0x0a,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
+ 0xff0000, 0 },
+ { 0, }
+};
-void pm3fb_build_options(void)
-{
- int i;
- char ts[128];
+/* For PCI drivers */
+static struct pci_driver pm3fb_driver = {
+ .name = "pm3fb",
+ .id_table = pm3fb_id_table,
+ .probe = pm3fb_probe,
+ .remove = __devexit_p(pm3fb_remove),
+};
- strcpy(g_options, "pm3fb");
- for (i = 0; i < PM3_MAX_BOARD ; i++)
- {
- if (mode[i])
- {
- sprintf(ts, ",mode:%d:%s", i, mode[i]);
- strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
- }
- if (disable[i] || off[i])
- {
- sprintf(ts, ",disable:%d:", i);
- strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
- }
- if (pciid[i])
- {
- sprintf(ts, ",pciid:%d:%s", i, pciid[i]);
- strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
- }
- if (noaccel[i])
- {
- sprintf(ts, ",noaccel:%d:", i);
- strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
- }
- if (font[i])
- {
- sprintf(ts, ",font:%d:%s", i, font[i]);
- strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
- }
- if (depth[i])
- {
- sprintf(ts, ",depth:%d:%d", i, depth[i]);
- strncat(g_options, ts, PM3_OPTIONS_SIZE - strlen(g_options));
- }
- }
- g_options[PM3_OPTIONS_SIZE - 1] = '\0';
- DPRINTK(1, "pm3fb use options: %s\n", g_options);
-}
+MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
-int init_module(void)
+int __init pm3fb_init(void)
{
- DTRACE;
+ /*
+ * For kernel boot options (in 'video=pm3fb:<options>' format)
+ */
+#ifndef MODULE
+ char *option = NULL;
- pm3fb_build_options();
+ if (fb_get_options("pm3fb", &option))
+ return -ENODEV;
+ pm3fb_setup(option);
+#endif
- pm3fb_init();
+ return pci_register_driver(&pm3fb_driver);
+}
- return 0;
+static void __exit pm3fb_exit(void)
+{
+ pci_unregister_driver(&pm3fb_driver);
}
-void cleanup_module(void)
+#ifndef MODULE
+ /*
+ * Setup
+ */
+
+/*
+ * Only necessary if your driver takes special options,
+ * otherwise we fall back on the generic fb_setup().
+ */
+int __init pm3fb_setup(char *options)
{
- DTRACE;
- {
- unsigned long i;
- struct pm3fb_info *l_fb_info;
- for (i = 0; i < PM3_MAX_BOARD; i++) {
- l_fb_info = &(fb_info[i]);
- pci_dev_put(l_fb_info->dev);
- if (l_fb_info->dev != NULL && !(disable[l_fb_info->board_num])) {
- if (l_fb_info->vIOBase != (unsigned char *) -1) {
- pm3fb_unmapIO(l_fb_info);
- release_mem_region(l_fb_info->p_fb,
- l_fb_info->fb_size);
- release_mem_region(l_fb_info->pIOBase,
- PM3_REGS_SIZE);
- }
- unregister_framebuffer(&l_fb_info->gen.info);
- }
- }
- }
+ /* Parse user speficied options (`video=pm3fb:') */
+ return 0;
}
#endif /* MODULE */
+
+module_init(pm3fb_init);
+module_exit(pm3fb_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 76e6ce353c8..a0e22ac483a 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -70,8 +70,6 @@ static int riva_gpio_getscl(void* data)
if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x04)
val = 1;
- val = VGA_RD08(par->riva.PCIO, 0x3d5);
-
return val;
}
diff --git a/fs/Makefile b/fs/Makefile
index 9edf4112bee..720c29d57a6 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -22,6 +22,10 @@ endif
obj-$(CONFIG_INOTIFY) += inotify.o
obj-$(CONFIG_INOTIFY_USER) += inotify_user.o
obj-$(CONFIG_EPOLL) += eventpoll.o
+obj-$(CONFIG_ANON_INODES) += anon_inodes.o
+obj-$(CONFIG_SIGNALFD) += signalfd.o
+obj-$(CONFIG_TIMERFD) += timerfd.o
+obj-$(CONFIG_EVENTFD) += eventfd.o
obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
nfsd-$(CONFIG_NFSD) := nfsctl.o
diff --git a/fs/afs/afs.h b/fs/afs/afs.h
index 52d0752265b..24525794814 100644
--- a/fs/afs/afs.h
+++ b/fs/afs/afs.h
@@ -16,6 +16,9 @@
#define AFS_MAXCELLNAME 64 /* maximum length of a cell name */
#define AFS_MAXVOLNAME 64 /* maximum length of a volume name */
+#define AFSNAMEMAX 256 /* maximum length of a filename plus NUL */
+#define AFSPATHMAX 1024 /* maximum length of a pathname plus NUL */
+#define AFSOPAQUEMAX 1024 /* maximum length of an opaque field */
typedef unsigned afs_volid_t;
typedef unsigned afs_vnodeid_t;
@@ -143,4 +146,24 @@ struct afs_volsync {
time_t creation; /* volume creation time */
};
+/*
+ * AFS volume status record
+ */
+struct afs_volume_status {
+ u32 vid; /* volume ID */
+ u32 parent_id; /* parent volume ID */
+ u8 online; /* true if volume currently online and available */
+ u8 in_service; /* true if volume currently in service */
+ u8 blessed; /* same as in_service */
+ u8 needs_salvage; /* true if consistency checking required */
+ u32 type; /* volume type (afs_voltype_t) */
+ u32 min_quota; /* minimum space set aside (blocks) */
+ u32 max_quota; /* maximum space this volume may occupy (blocks) */
+ u32 blocks_in_use; /* space this volume currently occupies (blocks) */
+ u32 part_blocks_avail; /* space available in volume's partition */
+ u32 part_max_blocks; /* size of volume's partition */
+};
+
+#define AFS_BLOCK_SIZE 1024
+
#endif /* AFS_H */
diff --git a/fs/afs/afs_fs.h b/fs/afs/afs_fs.h
index d963ef4daee..a18c374ebe0 100644
--- a/fs/afs/afs_fs.h
+++ b/fs/afs/afs_fs.h
@@ -28,7 +28,8 @@ enum AFS_FS_Operations {
FSMAKEDIR = 141, /* AFS Create a directory */
FSREMOVEDIR = 142, /* AFS Remove a directory */
FSGIVEUPCALLBACKS = 147, /* AFS Discard callback promises */
- FSGETVOLUMEINFO = 148, /* AFS Get root volume information */
+ FSGETVOLUMEINFO = 148, /* AFS Get information about a volume */
+ FSGETVOLUMESTATUS = 149, /* AFS Get volume status information */
FSGETROOTVOLUME = 151, /* AFS Get root volume name */
FSLOOKUP = 161, /* AFS lookup file in directory */
FSFETCHDATA64 = 65537, /* AFS Fetch file data */
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 2fb31276196..719af4fb15d 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -497,7 +497,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
ASSERTCMP(dentry->d_inode, ==, NULL);
- if (dentry->d_name.len > 255) {
+ if (dentry->d_name.len >= AFSNAMEMAX) {
_leave(" = -ENAMETOOLONG");
return ERR_PTR(-ENAMETOOLONG);
}
@@ -736,7 +736,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);
ret = -ENAMETOOLONG;
- if (dentry->d_name.len > 255)
+ if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
key = afs_request_key(dvnode->volume->cell);
@@ -801,7 +801,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
ret = -ENAMETOOLONG;
- if (dentry->d_name.len > 255)
+ if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
key = afs_request_key(dvnode->volume->cell);
@@ -847,7 +847,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
ret = -ENAMETOOLONG;
- if (dentry->d_name.len > 255)
+ if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
key = afs_request_key(dvnode->volume->cell);
@@ -921,7 +921,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, int mode,
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);
ret = -ENAMETOOLONG;
- if (dentry->d_name.len > 255)
+ if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
key = afs_request_key(dvnode->volume->cell);
@@ -990,7 +990,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
dentry->d_name.name);
ret = -ENAMETOOLONG;
- if (dentry->d_name.len > 255)
+ if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
key = afs_request_key(dvnode->volume->cell);
@@ -1038,11 +1038,11 @@ static int afs_symlink(struct inode *dir, struct dentry *dentry,
content);
ret = -ENAMETOOLONG;
- if (dentry->d_name.len > 255)
+ if (dentry->d_name.len >= AFSNAMEMAX)
goto error;
ret = -EINVAL;
- if (strlen(content) > 1023)
+ if (strlen(content) >= AFSPATHMAX)
goto error;
key = afs_request_key(dvnode->volume->cell);
@@ -1112,7 +1112,7 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
new_dentry->d_name.name);
ret = -ENAMETOOLONG;
- if (new_dentry->d_name.len > 255)
+ if (new_dentry->d_name.len >= AFSNAMEMAX)
goto error;
key = afs_request_key(orig_dvnode->volume->cell);
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 3e25795e5a4..9c0e721d9fc 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -236,7 +236,7 @@ static void afs_invalidatepage(struct page *page, unsigned long offset)
{
int ret = 1;
- kenter("{%lu},%lu", page->index, offset);
+ _enter("{%lu},%lu", page->index, offset);
BUG_ON(!PageLocked(page));
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 56cc0efa2a0..5dff1308b6f 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -202,6 +202,29 @@ static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
}
/*
+ * decode an AFSFetchVolumeStatus block
+ */
+static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
+ struct afs_volume_status *vs)
+{
+ const __be32 *bp = *_bp;
+
+ vs->vid = ntohl(*bp++);
+ vs->parent_id = ntohl(*bp++);
+ vs->online = ntohl(*bp++);
+ vs->in_service = ntohl(*bp++);
+ vs->blessed = ntohl(*bp++);
+ vs->needs_salvage = ntohl(*bp++);
+ vs->type = ntohl(*bp++);
+ vs->min_quota = ntohl(*bp++);
+ vs->max_quota = ntohl(*bp++);
+ vs->blocks_in_use = ntohl(*bp++);
+ vs->part_blocks_avail = ntohl(*bp++);
+ vs->part_max_blocks = ntohl(*bp++);
+ *_bp = bp;
+}
+
+/*
* deliver reply data to an FS.FetchStatus
*/
static int afs_deliver_fs_fetch_status(struct afs_call *call,
@@ -1450,3 +1473,278 @@ int afs_fs_setattr(struct afs_server *server, struct key *key,
return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
}
+
+/*
+ * deliver reply data to an FS.GetVolumeStatus
+ */
+static int afs_deliver_fs_get_volume_status(struct afs_call *call,
+ struct sk_buff *skb, bool last)
+{
+ const __be32 *bp;
+ char *p;
+ int ret;
+
+ _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
+
+ switch (call->unmarshall) {
+ case 0:
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the returned status record */
+ case 1:
+ _debug("extract status");
+ ret = afs_extract_data(call, skb, last, call->buffer,
+ 12 * 4);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+
+ bp = call->buffer;
+ xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the volume name length */
+ case 2:
+ ret = afs_extract_data(call, skb, last, &call->tmp, 4);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+
+ call->count = ntohl(call->tmp);
+ _debug("volname length: %u", call->count);
+ if (call->count >= AFSNAMEMAX)
+ return -EBADMSG;
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the volume name */
+ case 3:
+ _debug("extract volname");
+ if (call->count > 0) {
+ ret = afs_extract_data(call, skb, last, call->reply3,
+ call->count);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+ }
+
+ p = call->reply3;
+ p[call->count] = 0;
+ _debug("volname '%s'", p);
+
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the volume name padding */
+ if ((call->count & 3) == 0) {
+ call->unmarshall++;
+ goto no_volname_padding;
+ }
+ call->count = 4 - (call->count & 3);
+
+ case 4:
+ ret = afs_extract_data(call, skb, last, call->buffer,
+ call->count);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+
+ call->offset = 0;
+ call->unmarshall++;
+ no_volname_padding:
+
+ /* extract the offline message length */
+ case 5:
+ ret = afs_extract_data(call, skb, last, &call->tmp, 4);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+
+ call->count = ntohl(call->tmp);
+ _debug("offline msg length: %u", call->count);
+ if (call->count >= AFSNAMEMAX)
+ return -EBADMSG;
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the offline message */
+ case 6:
+ _debug("extract offline");
+ if (call->count > 0) {
+ ret = afs_extract_data(call, skb, last, call->reply3,
+ call->count);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+ }
+
+ p = call->reply3;
+ p[call->count] = 0;
+ _debug("offline '%s'", p);
+
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the offline message padding */
+ if ((call->count & 3) == 0) {
+ call->unmarshall++;
+ goto no_offline_padding;
+ }
+ call->count = 4 - (call->count & 3);
+
+ case 7:
+ ret = afs_extract_data(call, skb, last, call->buffer,
+ call->count);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+
+ call->offset = 0;
+ call->unmarshall++;
+ no_offline_padding:
+
+ /* extract the message of the day length */
+ case 8:
+ ret = afs_extract_data(call, skb, last, &call->tmp, 4);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+
+ call->count = ntohl(call->tmp);
+ _debug("motd length: %u", call->count);
+ if (call->count >= AFSNAMEMAX)
+ return -EBADMSG;
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the message of the day */
+ case 9:
+ _debug("extract motd");
+ if (call->count > 0) {
+ ret = afs_extract_data(call, skb, last, call->reply3,
+ call->count);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+ }
+
+ p = call->reply3;
+ p[call->count] = 0;
+ _debug("motd '%s'", p);
+
+ call->offset = 0;
+ call->unmarshall++;
+
+ /* extract the message of the day padding */
+ if ((call->count & 3) == 0) {
+ call->unmarshall++;
+ goto no_motd_padding;
+ }
+ call->count = 4 - (call->count & 3);
+
+ case 10:
+ ret = afs_extract_data(call, skb, last, call->buffer,
+ call->count);
+ switch (ret) {
+ case 0: break;
+ case -EAGAIN: return 0;
+ default: return ret;
+ }
+
+ call->offset = 0;
+ call->unmarshall++;
+ no_motd_padding:
+
+ case 11:
+ _debug("trailer %d", skb->len);
+ if (skb->len != 0)
+ return -EBADMSG;
+ break;
+ }
+
+ if (!last)
+ return 0;
+
+ _leave(" = 0 [done]");
+ return 0;
+}
+
+/*
+ * destroy an FS.GetVolumeStatus call
+ */
+static void afs_get_volume_status_call_destructor(struct afs_call *call)
+{
+ kfree(call->reply3);
+ call->reply3 = NULL;
+ afs_flat_call_destructor(call);
+}
+
+/*
+ * FS.GetVolumeStatus operation type
+ */
+static const struct afs_call_type afs_RXFSGetVolumeStatus = {
+ .name = "FS.GetVolumeStatus",
+ .deliver = afs_deliver_fs_get_volume_status,
+ .abort_to_error = afs_abort_to_error,
+ .destructor = afs_get_volume_status_call_destructor,
+};
+
+/*
+ * fetch the status of a volume
+ */
+int afs_fs_get_volume_status(struct afs_server *server,
+ struct key *key,
+ struct afs_vnode *vnode,
+ struct afs_volume_status *vs,
+ const struct afs_wait_mode *wait_mode)
+{
+ struct afs_call *call;
+ __be32 *bp;
+ void *tmpbuf;
+
+ _enter("");
+
+ tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
+ if (!tmpbuf)
+ return -ENOMEM;
+
+ call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
+ if (!call) {
+ kfree(tmpbuf);
+ return -ENOMEM;
+ }
+
+ call->key = key;
+ call->reply = vnode;
+ call->reply2 = vs;
+ call->reply3 = tmpbuf;
+ call->service_id = FS_SERVICE;
+ call->port = htons(AFS_FS_PORT);
+
+ /* marshall the parameters */
+ bp = call->request;
+ bp[0] = htonl(FSGETVOLUMESTATUS);
+ bp[1] = htonl(vnode->fid.vid);
+
+ return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
+}
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 515a5d12d8f..47f5fed7195 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -209,11 +209,15 @@ bad_inode:
*/
void afs_zap_data(struct afs_vnode *vnode)
{
- _enter("zap data {%x:%u}", vnode->fid.vid, vnode->fid.vnode);
+ _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
/* nuke all the non-dirty pages that aren't locked, mapped or being
- * written back */
- invalidate_remote_inode(&vnode->vfs_inode);
+ * written back in a regular file and completely discard the pages in a
+ * directory or symlink */
+ if (S_ISREG(vnode->vfs_inode.i_mode))
+ invalidate_remote_inode(&vnode->vfs_inode);
+ else
+ invalidate_inode_pages2(vnode->vfs_inode.i_mapping);
}
/*
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index a30d4fa768e..4953ba5a6f4 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -506,6 +506,10 @@ extern int afs_fs_store_data(struct afs_server *, struct afs_writeback *,
extern int afs_fs_setattr(struct afs_server *, struct key *,
struct afs_vnode *, struct iattr *,
const struct afs_wait_mode *);
+extern int afs_fs_get_volume_status(struct afs_server *, struct key *,
+ struct afs_vnode *,
+ struct afs_volume_status *,
+ const struct afs_wait_mode *);
/*
* inode.c
@@ -672,6 +676,8 @@ extern int afs_vnode_rename(struct afs_vnode *, struct afs_vnode *,
extern int afs_vnode_store_data(struct afs_writeback *, pgoff_t, pgoff_t,
unsigned, unsigned);
extern int afs_vnode_setattr(struct afs_vnode *, struct key *, struct iattr *);
+extern int afs_vnode_get_volume_status(struct afs_vnode *, struct key *,
+ struct afs_volume_status *);
/*
* volume.c
diff --git a/fs/afs/super.c b/fs/afs/super.c
index d24be334b60..579af632c8e 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -21,22 +21,20 @@
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/parser.h>
+#include <linux/statfs.h>
#include "internal.h"
#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
static void afs_i_init_once(void *foo, struct kmem_cache *cachep,
unsigned long flags);
-
static int afs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name,
void *data, struct vfsmount *mnt);
-
static struct inode *afs_alloc_inode(struct super_block *sb);
-
static void afs_put_super(struct super_block *sb);
-
static void afs_destroy_inode(struct inode *inode);
+static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
struct file_system_type afs_fs_type = {
.owner = THIS_MODULE,
@@ -47,7 +45,7 @@ struct file_system_type afs_fs_type = {
};
static const struct super_operations afs_super_ops = {
- .statfs = simple_statfs,
+ .statfs = afs_statfs,
.alloc_inode = afs_alloc_inode,
.drop_inode = generic_delete_inode,
.write_inode = afs_write_inode,
@@ -488,6 +486,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
vnode->flags = 1 << AFS_VNODE_UNSET;
vnode->cb_promised = false;
+ _leave(" = %p", &vnode->vfs_inode);
return &vnode->vfs_inode;
}
@@ -498,7 +497,7 @@ static void afs_destroy_inode(struct inode *inode)
{
struct afs_vnode *vnode = AFS_FS_I(inode);
- _enter("{%lu}", inode->i_ino);
+ _enter("%p{%x:%u}", inode, vnode->fid.vid, vnode->fid.vnode);
_debug("DESTROY INODE %p", inode);
@@ -507,3 +506,36 @@ static void afs_destroy_inode(struct inode *inode)
kmem_cache_free(afs_inode_cachep, vnode);
atomic_dec(&afs_count_active_inodes);
}
+
+/*
+ * return information about an AFS volume
+ */
+static int afs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ struct afs_volume_status vs;
+ struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
+ struct key *key;
+ int ret;
+
+ key = afs_request_key(vnode->volume->cell);
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+
+ ret = afs_vnode_get_volume_status(vnode, key, &vs);
+ key_put(key);
+ if (ret < 0) {
+ _leave(" = %d", ret);
+ return ret;
+ }
+
+ buf->f_type = dentry->d_sb->s_magic;
+ buf->f_bsize = AFS_BLOCK_SIZE;
+ buf->f_namelen = AFSNAMEMAX - 1;
+
+ if (vs.max_quota == 0)
+ buf->f_blocks = vs.part_max_blocks;
+ else
+ buf->f_blocks = vs.max_quota;
+ buf->f_bavail = buf->f_bfree = buf->f_blocks - vs.blocks_in_use;
+ return 0;
+}
diff --git a/fs/afs/vnode.c b/fs/afs/vnode.c
index ec814660209..c36c98ce2c3 100644
--- a/fs/afs/vnode.c
+++ b/fs/afs/vnode.c
@@ -175,24 +175,33 @@ static void afs_vnode_deleted_remotely(struct afs_vnode *vnode)
{
struct afs_server *server;
+ _enter("{%p}", vnode->server);
+
set_bit(AFS_VNODE_DELETED, &vnode->flags);
server = vnode->server;
- if (vnode->cb_promised) {
- spin_lock(&server->cb_lock);
+ if (server) {
if (vnode->cb_promised) {
- rb_erase(&vnode->cb_promise, &server->cb_promises);
- vnode->cb_promised = false;
+ spin_lock(&server->cb_lock);
+ if (vnode->cb_promised) {
+ rb_erase(&vnode->cb_promise,
+ &server->cb_promises);
+ vnode->cb_promised = false;
+ }
+ spin_unlock(&server->cb_lock);
}
- spin_unlock(&server->cb_lock);
- }
- spin_lock(&vnode->server->fs_lock);
- rb_erase(&vnode->server_rb, &vnode->server->fs_vnodes);
- spin_unlock(&vnode->server->fs_lock);
+ spin_lock(&server->fs_lock);
+ rb_erase(&vnode->server_rb, &server->fs_vnodes);
+ spin_unlock(&server->fs_lock);
- vnode->server = NULL;
- afs_put_server(server);
+ vnode->server = NULL;
+ afs_put_server(server);
+ } else {
+ ASSERT(!vnode->cb_promised);
+ }
+
+ _leave("");
}
/*
@@ -225,7 +234,7 @@ void afs_vnode_finalise_status_update(struct afs_vnode *vnode,
*/
static void afs_vnode_status_update_failed(struct afs_vnode *vnode, int ret)
{
- _enter("%p,%d", vnode, ret);
+ _enter("{%x:%u},%d", vnode->fid.vid, vnode->fid.vnode, ret);
spin_lock(&vnode->lock);
@@ -860,3 +869,55 @@ no_server:
spin_unlock(&vnode->lock);
return PTR_ERR(server);
}
+
+/*
+ * get the status of a volume
+ */
+int afs_vnode_get_volume_status(struct afs_vnode *vnode, struct key *key,
+ struct afs_volume_status *vs)
+{
+ struct afs_server *server;
+ int ret;
+
+ _enter("%s{%x:%u.%u},%x,",
+ vnode->volume->vlocation->vldb.name,
+ vnode->fid.vid,
+ vnode->fid.vnode,
+ vnode->fid.unique,
+ key_serial(key));
+
+ /* this op will fetch the status */
+ spin_lock(&vnode->lock);
+ vnode->update_cnt++;
+ spin_unlock(&vnode->lock);
+
+ do {
+ /* pick a server to query */
+ server = afs_volume_pick_fileserver(vnode);
+ if (IS_ERR(server))
+ goto no_server;
+
+ _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr));
+
+ ret = afs_fs_get_volume_status(server, key, vnode, vs, &afs_sync_call);
+
+ } while (!afs_volume_release_fileserver(vnode, server, ret));
+
+ /* adjust the flags */
+ if (ret == 0) {
+ afs_vnode_finalise_status_update(vnode, server);
+ afs_put_server(server);
+ } else {
+ afs_vnode_status_update_failed(vnode, ret);
+ }
+
+ _leave(" = %d", ret);
+ return ret;
+
+no_server:
+ spin_lock(&vnode->lock);
+ vnode->update_cnt--;
+ ASSERTCMP(vnode->update_cnt, >=, 0);
+ spin_unlock(&vnode->lock);
+ return PTR_ERR(server);
+}
diff --git a/fs/afs/write.c b/fs/afs/write.c
index 67ae4dbf66b..28f37516c12 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -395,8 +395,9 @@ static int afs_write_back_from_locked_page(struct afs_writeback *wb,
if (n == 0)
goto no_more;
if (pages[0]->index != start) {
- for (n--; n >= 0; n--)
- put_page(pages[n]);
+ do {
+ put_page(pages[--n]);
+ } while (n > 0);
goto no_more;
}
diff --git a/fs/aio.c b/fs/aio.c
index ac1c1587aa0..dbe699e9828 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -30,6 +30,7 @@
#include <linux/highmem.h>
#include <linux/workqueue.h>
#include <linux/security.h>
+#include <linux/eventfd.h>
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
@@ -417,6 +418,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx)
req->private = NULL;
req->ki_iovec = NULL;
INIT_LIST_HEAD(&req->ki_run_list);
+ req->ki_eventfd = ERR_PTR(-EINVAL);
/* Check if the completion queue has enough free space to
* accept an event from this io.
@@ -458,6 +460,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req)
{
assert_spin_locked(&ctx->ctx_lock);
+ if (!IS_ERR(req->ki_eventfd))
+ fput(req->ki_eventfd);
if (req->ki_dtor)
req->ki_dtor(req);
if (req->ki_iovec != &req->ki_inline_vec)
@@ -942,6 +946,14 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2)
return 1;
}
+ /*
+ * Check if the user asked us to deliver the result through an
+ * eventfd. The eventfd_signal() function is safe to be called
+ * from IRQ context.
+ */
+ if (!IS_ERR(iocb->ki_eventfd))
+ eventfd_signal(iocb->ki_eventfd, 1);
+
info = &ctx->ring_info;
/* add a completion event to the ring buffer.
@@ -1526,8 +1538,7 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
ssize_t ret;
/* enforce forwards compatibility on users */
- if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2 ||
- iocb->aio_reserved3)) {
+ if (unlikely(iocb->aio_reserved1 || iocb->aio_reserved2)) {
pr_debug("EINVAL: io_submit: reserve field set\n");
return -EINVAL;
}
@@ -1551,6 +1562,19 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
fput(file);
return -EAGAIN;
}
+ if (iocb->aio_flags & IOCB_FLAG_RESFD) {
+ /*
+ * If the IOCB_FLAG_RESFD flag of aio_flags is set, get an
+ * instance of the file* now. The file descriptor must be
+ * an eventfd() fd, and will be signaled for each completed
+ * event using the eventfd_signal() function.
+ */
+ req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd);
+ if (unlikely(IS_ERR(req->ki_eventfd))) {
+ ret = PTR_ERR(req->ki_eventfd);
+ goto out_put_req;
+ }
+ }
req->ki_filp = file;
ret = put_user(req->ki_key, &user_iocb->aio_key);
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
new file mode 100644
index 00000000000..40fe3a3222e
--- /dev/null
+++ b/fs/anon_inodes.c
@@ -0,0 +1,200 @@
+/*
+ * fs/anon_inodes.c
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ * Thanks to Arnd Bergmann for code review and suggestions.
+ * More changes for Thomas Gleixner suggestions.
+ *
+ */
+
+#include <linux/file.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/magic.h>
+#include <linux/anon_inodes.h>
+
+#include <asm/uaccess.h>
+
+static struct vfsmount *anon_inode_mnt __read_mostly;
+static struct inode *anon_inode_inode;
+static const struct file_operations anon_inode_fops;
+
+static int anon_inodefs_get_sb(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data,
+ struct vfsmount *mnt)
+{
+ return get_sb_pseudo(fs_type, "anon_inode:", NULL, ANON_INODE_FS_MAGIC,
+ mnt);
+}
+
+static int anon_inodefs_delete_dentry(struct dentry *dentry)
+{
+ /*
+ * We faked vfs to believe the dentry was hashed when we created it.
+ * Now we restore the flag so that dput() will work correctly.
+ */
+ dentry->d_flags |= DCACHE_UNHASHED;
+ return 1;
+}
+
+static struct file_system_type anon_inode_fs_type = {
+ .name = "anon_inodefs",
+ .get_sb = anon_inodefs_get_sb,
+ .kill_sb = kill_anon_super,
+};
+static struct dentry_operations anon_inodefs_dentry_operations = {
+ .d_delete = anon_inodefs_delete_dentry,
+};
+
+/**
+ * anon_inode_getfd - creates a new file instance by hooking it up to and
+ * anonymous inode, and a dentry that describe the "class"
+ * of the file
+ *
+ * @pfd: [out] pointer to the file descriptor
+ * @dpinode: [out] pointer to the inode
+ * @pfile: [out] pointer to the file struct
+ * @name: [in] name of the "class" of the new file
+ * @fops [in] file operations for the new file
+ * @priv [in] private data for the new file (will be file's private_data)
+ *
+ * Creates a new file by hooking it on a single inode. This is useful for files
+ * that do not need to have a full-fledged inode in order to operate correctly.
+ * All the files created with anon_inode_getfd() will share a single inode, by
+ * hence saving memory and avoiding code duplication for the file/inode/dentry
+ * setup.
+ */
+int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
+ const char *name, const struct file_operations *fops,
+ void *priv)
+{
+ struct qstr this;
+ struct dentry *dentry;
+ struct inode *inode;
+ struct file *file;
+ int error, fd;
+
+ if (IS_ERR(anon_inode_inode))
+ return -ENODEV;
+ file = get_empty_filp();
+ if (!file)
+ return -ENFILE;
+
+ inode = igrab(anon_inode_inode);
+ if (IS_ERR(inode)) {
+ error = PTR_ERR(inode);
+ goto err_put_filp;
+ }
+
+ error = get_unused_fd();
+ if (error < 0)
+ goto err_iput;
+ fd = error;
+
+ /*
+ * Link the inode to a directory entry by creating a unique name
+ * using the inode sequence number.
+ */
+ error = -ENOMEM;
+ this.name = name;
+ this.len = strlen(name);
+ this.hash = 0;
+ dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
+ if (!dentry)
+ goto err_put_unused_fd;
+ dentry->d_op = &anon_inodefs_dentry_operations;
+ /* Do not publish this dentry inside the global dentry hash table */
+ dentry->d_flags &= ~DCACHE_UNHASHED;
+ d_instantiate(dentry, inode);
+
+ file->f_path.mnt = mntget(anon_inode_mnt);
+ file->f_path.dentry = dentry;
+ file->f_mapping = inode->i_mapping;
+
+ file->f_pos = 0;
+ file->f_flags = O_RDWR;
+ file->f_op = fops;
+ file->f_mode = FMODE_READ | FMODE_WRITE;
+ file->f_version = 0;
+ file->private_data = priv;
+
+ fd_install(fd, file);
+
+ *pfd = fd;
+ *pinode = inode;
+ *pfile = file;
+ return 0;
+
+err_put_unused_fd:
+ put_unused_fd(fd);
+err_iput:
+ iput(inode);
+err_put_filp:
+ put_filp(file);
+ return error;
+}
+
+/*
+ * A single inode exist for all anon_inode files. Contrary to pipes,
+ * anon_inode inodes has no per-instance data associated, so we can avoid
+ * the allocation of multiple of them.
+ */
+static struct inode *anon_inode_mkinode(void)
+{
+ struct inode *inode = new_inode(anon_inode_mnt->mnt_sb);
+
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ inode->i_fop = &anon_inode_fops;
+
+ /*
+ * Mark the inode dirty from the very beginning,
+ * that way it will never be moved to the dirty
+ * list because mark_inode_dirty() will think
+ * that it already _is_ on the dirty list.
+ */
+ inode->i_state = I_DIRTY;
+ inode->i_mode = S_IRUSR | S_IWUSR;
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ return inode;
+}
+
+static int __init anon_inode_init(void)
+{
+ int error;
+
+ error = register_filesystem(&anon_inode_fs_type);
+ if (error)
+ goto err_exit;
+ anon_inode_mnt = kern_mount(&anon_inode_fs_type);
+ if (IS_ERR(anon_inode_mnt)) {
+ error = PTR_ERR(anon_inode_mnt);
+ goto err_unregister_filesystem;
+ }
+ anon_inode_inode = anon_inode_mkinode();
+ if (IS_ERR(anon_inode_inode)) {
+ error = PTR_ERR(anon_inode_inode);
+ goto err_mntput;
+ }
+
+ return 0;
+
+err_mntput:
+ mntput(anon_inode_mnt);
+err_unregister_filesystem:
+ unregister_filesystem(&anon_inode_fs_type);
+err_exit:
+ panic(KERN_ERR "anon_inode_init() failed (%d)\n", error);
+}
+
+fs_initcall(anon_inode_init);
+
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 4ef544434b5..8b4cca3c470 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -101,7 +101,7 @@ struct autofs_symlink {
struct autofs_sb_info {
u32 magic;
struct file *pipe;
- pid_t oz_pgrp;
+ struct pid *oz_pgrp;
int catatonic;
struct super_block *sb;
unsigned long exp_timeout;
@@ -122,7 +122,7 @@ static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
filesystem without "magic".) */
static inline int autofs_oz_mode(struct autofs_sb_info *sbi) {
- return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+ return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp;
}
/* Hash operations */
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index aa0b61ff827..e7204d71acc 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -34,12 +34,14 @@ void autofs_kill_sb(struct super_block *sb)
if (!sbi)
goto out_kill_sb;
- if ( !sbi->catatonic )
+ if (!sbi->catatonic)
autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
+ put_pid(sbi->oz_pgrp);
+
autofs_hash_nuke(sbi);
- for ( n = 0 ; n < AUTOFS_MAX_SYMLINKS ; n++ ) {
- if ( test_bit(n, sbi->symlink_bitmap) )
+ for (n = 0; n < AUTOFS_MAX_SYMLINKS; n++) {
+ if (test_bit(n, sbi->symlink_bitmap))
kfree(sbi->symlink[n].data);
}
@@ -69,7 +71,8 @@ static match_table_t autofs_tokens = {
{Opt_err, NULL}
};
-static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, pid_t *pgrp, int *minproto, int *maxproto)
+static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
+ pid_t *pgrp, int *minproto, int *maxproto)
{
char *p;
substring_t args[MAX_OPT_ARGS];
@@ -138,9 +141,10 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
int pipefd;
struct autofs_sb_info *sbi;
int minproto, maxproto;
+ pid_t pgid;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
- if ( !sbi )
+ if (!sbi)
goto fail_unlock;
DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
@@ -149,7 +153,6 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
sbi->pipe = NULL;
sbi->catatonic = 1;
sbi->exp_timeout = 0;
- sbi->oz_pgrp = process_group(current);
autofs_initialize_hash(&sbi->dirhash);
sbi->queues = NULL;
memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
@@ -169,26 +172,36 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
goto fail_iput;
/* Can this call block? - WTF cares? s is locked. */
- if ( parse_options(data,&pipefd,&root_inode->i_uid,&root_inode->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
+ if (parse_options(data, &pipefd, &root_inode->i_uid,
+ &root_inode->i_gid, &pgid, &minproto,
+ &maxproto)) {
printk("autofs: called with bogus options\n");
goto fail_dput;
}
/* Couldn't this be tested earlier? */
- if ( minproto > AUTOFS_PROTO_VERSION ||
- maxproto < AUTOFS_PROTO_VERSION ) {
+ if (minproto > AUTOFS_PROTO_VERSION ||
+ maxproto < AUTOFS_PROTO_VERSION) {
printk("autofs: kernel does not match daemon version\n");
goto fail_dput;
}
- DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, sbi->oz_pgrp));
+ DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, pgid));
+ sbi->oz_pgrp = find_get_pid(pgid);
+
+ if (!sbi->oz_pgrp) {
+ printk("autofs: could not find process group %d\n", pgid);
+ goto fail_dput;
+ }
+
pipe = fget(pipefd);
- if ( !pipe ) {
+ if (!pipe) {
printk("autofs: could not open pipe file descriptor\n");
- goto fail_dput;
+ goto fail_put_pid;
}
- if ( !pipe->f_op || !pipe->f_op->write )
+
+ if (!pipe->f_op || !pipe->f_op->write)
goto fail_fput;
sbi->pipe = pipe;
sbi->catatonic = 0;
@@ -202,6 +215,8 @@ int autofs_fill_super(struct super_block *s, void *data, int silent)
fail_fput:
printk("autofs: pipe file descriptor does not contain proper ops\n");
fput(pipe);
+fail_put_pid:
+ put_pid(sbi->oz_pgrp);
fail_dput:
dput(root);
goto fail_free;
@@ -230,7 +245,7 @@ static void autofs_read_inode(struct inode *inode)
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->i_blocks = 0;
- if ( ino == AUTOFS_ROOT_INO ) {
+ if (ino == AUTOFS_ROOT_INO) {
inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
inode->i_op = &autofs_root_inode_operations;
inode->i_fop = &autofs_root_operations;
@@ -241,12 +256,12 @@ static void autofs_read_inode(struct inode *inode)
inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
- if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) {
+ if (ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO) {
/* Symlink inode - should be in symlink list */
struct autofs_symlink *sl;
n = ino - AUTOFS_FIRST_SYMLINK;
- if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
+ if (n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
printk("autofs: Looking for bad symlink inode %u\n", (unsigned int) ino);
return;
}
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index f2597205939..c1489533277 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -67,8 +67,8 @@ static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldi
filp->f_pos = ++nr;
/* fall through */
default:
- while ( onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent) ) {
- if ( !ent->dentry || d_mountpoint(ent->dentry) ) {
+ while (onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent)) {
+ if (!ent->dentry || d_mountpoint(ent->dentry)) {
if (filldir(dirent,ent->name,ent->len,onr,ent->ino,DT_UNKNOWN) < 0)
goto out;
filp->f_pos = nr;
@@ -88,10 +88,10 @@ static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, str
struct autofs_dir_ent *ent;
int status = 0;
- if ( !(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name)) ) {
+ if (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name))) {
do {
- if ( status && dentry->d_inode ) {
- if ( status != -ENOENT )
+ if (status && dentry->d_inode) {
+ if (status != -ENOENT)
printk("autofs warning: lookup failure on positive dentry, status = %d, name = %s\n", status, dentry->d_name.name);
return 0; /* Try to get the kernel to invalidate this dentry */
}
@@ -106,7 +106,7 @@ static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, str
return 1;
}
status = autofs_wait(sbi, &dentry->d_name);
- } while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name)) );
+ } while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name)));
}
/* Abuse this field as a pointer to the directory entry, used to
@@ -124,13 +124,13 @@ static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, str
/* If this is a directory that isn't a mount point, bitch at the
daemon and fix it in user space */
- if ( S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry) ) {
+ if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) {
return !autofs_wait(sbi, &dentry->d_name);
}
/* We don't update the usages for the autofs daemon itself, this
is necessary for recursive autofs mounts */
- if ( !autofs_oz_mode(sbi) ) {
+ if (!autofs_oz_mode(sbi)) {
autofs_update_usage(&sbi->dirhash,ent);
}
@@ -157,7 +157,7 @@ static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd)
sbi = autofs_sbi(dir->i_sb);
/* Pending dentry */
- if ( dentry->d_flags & DCACHE_AUTOFS_PENDING ) {
+ if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
if (autofs_oz_mode(sbi))
res = 1;
else
@@ -173,7 +173,7 @@ static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd)
}
/* Check for a non-mountpoint directory */
- if ( S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry) ) {
+ if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) {
if (autofs_oz_mode(sbi))
res = 1;
else
@@ -183,9 +183,9 @@ static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd)
}
/* Update the usage list */
- if ( !autofs_oz_mode(sbi) ) {
+ if (!autofs_oz_mode(sbi)) {
ent = (struct autofs_dir_ent *) dentry->d_time;
- if ( ent )
+ if (ent)
autofs_update_usage(&sbi->dirhash,ent);
}
unlock_kernel();
@@ -213,8 +213,10 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
sbi = autofs_sbi(dir->i_sb);
oz_mode = autofs_oz_mode(sbi);
- DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n",
- current->pid, process_group(current), sbi->catatonic, oz_mode));
+ DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, "
+ "oz_mode = %d\n", pid_nr(task_pid(current)),
+ process_group(current), sbi->catatonic,
+ oz_mode));
/*
* Mark the dentry incomplete, but add it. This is needed so
@@ -258,7 +260,7 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
* doesn't do the right thing for all system calls, but it should
* be OK for the operations we permit from an autofs.
*/
- if ( dentry->d_inode && d_unhashed(dentry) )
+ if (dentry->d_inode && d_unhashed(dentry))
return ERR_PTR(-ENOENT);
return NULL;
@@ -277,18 +279,18 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
autofs_say(dentry->d_name.name,dentry->d_name.len);
lock_kernel();
- if ( !autofs_oz_mode(sbi) ) {
+ if (!autofs_oz_mode(sbi)) {
unlock_kernel();
return -EACCES;
}
- if ( autofs_hash_lookup(dh, &dentry->d_name) ) {
+ if (autofs_hash_lookup(dh, &dentry->d_name)) {
unlock_kernel();
return -EEXIST;
}
n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS);
- if ( n >= AUTOFS_MAX_SYMLINKS ) {
+ if (n >= AUTOFS_MAX_SYMLINKS) {
unlock_kernel();
return -ENOSPC;
}
@@ -297,14 +299,14 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
sl = &sbi->symlink[n];
sl->len = strlen(symname);
sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
- if ( !sl->data ) {
+ if (!sl->data) {
clear_bit(n,sbi->symlink_bitmap);
unlock_kernel();
return -ENOSPC;
}
ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
- if ( !ent ) {
+ if (!ent) {
kfree(sl->data);
clear_bit(n,sbi->symlink_bitmap);
unlock_kernel();
@@ -312,7 +314,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
}
ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
- if ( !ent->name ) {
+ if (!ent->name) {
kfree(sl->data);
kfree(ent);
clear_bit(n,sbi->symlink_bitmap);
@@ -354,23 +356,23 @@ static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
/* This allows root to remove symlinks */
lock_kernel();
- if ( !autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) ) {
+ if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) {
unlock_kernel();
return -EACCES;
}
ent = autofs_hash_lookup(dh, &dentry->d_name);
- if ( !ent ) {
+ if (!ent) {
unlock_kernel();
return -ENOENT;
}
n = ent->ino - AUTOFS_FIRST_SYMLINK;
- if ( n >= AUTOFS_MAX_SYMLINKS ) {
+ if (n >= AUTOFS_MAX_SYMLINKS) {
unlock_kernel();
return -EISDIR; /* It's a directory, dummy */
}
- if ( !test_bit(n,sbi->symlink_bitmap) ) {
+ if (!test_bit(n,sbi->symlink_bitmap)) {
unlock_kernel();
return -EINVAL; /* Nonexistent symlink? Shouldn't happen */
}
@@ -392,23 +394,23 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
struct autofs_dir_ent *ent;
lock_kernel();
- if ( !autofs_oz_mode(sbi) ) {
+ if (!autofs_oz_mode(sbi)) {
unlock_kernel();
return -EACCES;
}
ent = autofs_hash_lookup(dh, &dentry->d_name);
- if ( !ent ) {
+ if (!ent) {
unlock_kernel();
return -ENOENT;
}
- if ( (unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO ) {
+ if ((unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO) {
unlock_kernel();
return -ENOTDIR; /* Not a directory */
}
- if ( ent->dentry != dentry ) {
+ if (ent->dentry != dentry) {
printk("autofs_rmdir: odentry != dentry for entry %s\n", dentry->d_name.name);
}
@@ -429,18 +431,18 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
ino_t ino;
lock_kernel();
- if ( !autofs_oz_mode(sbi) ) {
+ if (!autofs_oz_mode(sbi)) {
unlock_kernel();
return -EACCES;
}
ent = autofs_hash_lookup(dh, &dentry->d_name);
- if ( ent ) {
+ if (ent) {
unlock_kernel();
return -EEXIST;
}
- if ( sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO ) {
+ if (sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO) {
printk("autofs: Out of inode numbers -- what the heck did you do??\n");
unlock_kernel();
return -ENOSPC;
@@ -448,13 +450,13 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
ino = sbi->next_dir_ino++;
ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
- if ( !ent ) {
+ if (!ent) {
unlock_kernel();
return -ENOSPC;
}
ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
- if ( !ent->name ) {
+ if (!ent->name) {
kfree(ent);
unlock_kernel();
return -ENOSPC;
@@ -483,7 +485,7 @@ static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
put_user(sbi->exp_timeout / HZ, p))
return -EFAULT;
- if ( ntimeout > ULONG_MAX/HZ )
+ if (ntimeout > ULONG_MAX/HZ)
sbi->exp_timeout = 0;
else
sbi->exp_timeout = ntimeout * HZ;
@@ -511,15 +513,14 @@ static inline int autofs_expire_run(struct super_block *sb,
pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
pkt.hdr.type = autofs_ptype_expire;
- if ( !sbi->exp_timeout ||
- !(ent = autofs_expire(sb,sbi,mnt)) )
+ if (!sbi->exp_timeout || !(ent = autofs_expire(sb,sbi,mnt)))
return -EAGAIN;
pkt.len = ent->len;
memcpy(pkt.name, ent->name, pkt.len);
pkt.name[pkt.len] = '\0';
- if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) )
+ if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)))
return -EFAULT;
return 0;
@@ -537,11 +538,11 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
- if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
- _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
+ if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
+ _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
return -ENOTTY;
- if ( !autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
+ if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
return -EPERM;
switch(cmd) {
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 5769a2f9ad6..692364e8ffc 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -218,8 +218,7 @@ static match_table_t tokens = {
};
static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
- pid_t *pgrp, unsigned int *type,
- int *minproto, int *maxproto)
+ pid_t *pgrp, unsigned int *type, int *minproto, int *maxproto)
{
char *p;
substring_t args[MAX_OPT_ARGS];
@@ -314,7 +313,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
struct autofs_info *ino;
sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
- if ( !sbi )
+ if (!sbi)
goto fail_unlock;
DPRINTK("starting up, sbi = %p",sbi);
@@ -363,10 +362,9 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
root->d_fsdata = ino;
/* Can this call block? */
- if (parse_options(data, &pipefd,
- &root_inode->i_uid, &root_inode->i_gid,
- &sbi->oz_pgrp, &sbi->type,
- &sbi->min_proto, &sbi->max_proto)) {
+ if (parse_options(data, &pipefd, &root_inode->i_uid, &root_inode->i_gid,
+ &sbi->oz_pgrp, &sbi->type, &sbi->min_proto,
+ &sbi->max_proto)) {
printk("autofs: called with bogus options\n");
goto fail_dput;
}
@@ -396,11 +394,11 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
DPRINTK("pipe fd = %d, pgrp = %u", pipefd, sbi->oz_pgrp);
pipe = fget(pipefd);
- if ( !pipe ) {
+ if (!pipe) {
printk("autofs: could not open pipe file descriptor\n");
goto fail_dput;
}
- if ( !pipe->f_op || !pipe->f_op->write )
+ if (!pipe->f_op || !pipe->f_op->write)
goto fail_fput;
sbi->pipe = pipe;
sbi->pipefd = pipefd;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 15170f4e13a..2d4c8a3e604 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -759,7 +759,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
struct autofs_info *p_ino;
/* This allows root to remove symlinks */
- if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
+ if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
return -EACCES;
if (atomic_dec_and_test(&ino->count)) {
@@ -833,7 +833,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
struct autofs_info *p_ino;
struct inode *inode;
- if ( !autofs4_oz_mode(sbi) )
+ if (!autofs4_oz_mode(sbi))
return -EACCES;
DPRINTK("dentry %p, creating %.*s",
@@ -871,11 +871,11 @@ static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi,
int rv;
unsigned long ntimeout;
- if ( (rv = get_user(ntimeout, p)) ||
- (rv = put_user(sbi->exp_timeout/HZ, p)) )
+ if ((rv = get_user(ntimeout, p)) ||
+ (rv = put_user(sbi->exp_timeout/HZ, p)))
return rv;
- if ( ntimeout > ULONG_MAX/HZ )
+ if (ntimeout > ULONG_MAX/HZ)
sbi->exp_timeout = 0;
else
sbi->exp_timeout = ntimeout * HZ;
@@ -906,7 +906,7 @@ static inline int autofs4_ask_reghost(struct autofs_sb_info *sbi, int __user *p)
DPRINTK("returning %d", sbi->needs_reghost);
status = put_user(sbi->needs_reghost, p);
- if ( status )
+ if (status)
return status;
sbi->needs_reghost = 0;
@@ -975,11 +975,11 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp,
DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u",
cmd,arg,sbi,process_group(current));
- if ( _IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
- _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT )
+ if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
+ _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
return -ENOTTY;
- if ( !autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) )
+ if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
return -EPERM;
switch(cmd) {
diff --git a/fs/compat.c b/fs/compat.c
index 9cf75df9b2b..7b21b0a8259 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -46,6 +46,7 @@
#include <linux/tsacct_kern.h>
#include <linux/security.h>
#include <linux/highmem.h>
+#include <linux/signal.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/eventpoll.h>
@@ -2199,3 +2200,51 @@ asmlinkage long compat_sys_epoll_pwait(int epfd,
#endif /* TIF_RESTORE_SIGMASK */
#endif /* CONFIG_EPOLL */
+
+#ifdef CONFIG_SIGNALFD
+
+asmlinkage long compat_sys_signalfd(int ufd,
+ const compat_sigset_t __user *sigmask,
+ compat_size_t sigsetsize)
+{
+ compat_sigset_t ss32;
+ sigset_t tmp;
+ sigset_t __user *ksigmask;
+
+ if (sigsetsize != sizeof(compat_sigset_t))
+ return -EINVAL;
+ if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
+ return -EFAULT;
+ sigset_from_compat(&tmp, &ss32);
+ ksigmask = compat_alloc_user_space(sizeof(sigset_t));
+ if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t)))
+ return -EFAULT;
+
+ return sys_signalfd(ufd, ksigmask, sizeof(sigset_t));
+}
+
+#endif /* CONFIG_SIGNALFD */
+
+#ifdef CONFIG_TIMERFD
+
+asmlinkage long compat_sys_timerfd(int ufd, int clockid, int flags,
+ const struct compat_itimerspec __user *utmr)
+{
+ long res;
+ struct itimerspec t;
+ struct itimerspec __user *ut;
+
+ res = -EFAULT;
+ if (get_compat_itimerspec(&t, utmr))
+ goto err_exit;
+ ut = compat_alloc_user_space(sizeof(*ut));
+ if (copy_to_user(ut, &t, sizeof(t)) )
+ goto err_exit;
+
+ res = sys_timerfd(ufd, clockid, flags, ut);
+err_exit:
+ return res;
+}
+
+#endif /* CONFIG_TIMERFD */
+
diff --git a/fs/eventfd.c b/fs/eventfd.c
new file mode 100644
index 00000000000..480e2b3c416
--- /dev/null
+++ b/fs/eventfd.c
@@ -0,0 +1,228 @@
+/*
+ * fs/eventfd.c
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#include <linux/file.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/anon_inodes.h>
+#include <linux/eventfd.h>
+
+struct eventfd_ctx {
+ spinlock_t lock;
+ wait_queue_head_t wqh;
+ /*
+ * Every time that a write(2) is performed on an eventfd, the
+ * value of the __u64 being written is added to "count" and a
+ * wakeup is performed on "wqh". A read(2) will return the "count"
+ * value to userspace, and will reset "count" to zero. The kernel
+ * size eventfd_signal() also, adds to the "count" counter and
+ * issue a wakeup.
+ */
+ __u64 count;
+};
+
+/*
+ * Adds "n" to the eventfd counter "count". Returns "n" in case of
+ * success, or a value lower then "n" in case of coutner overflow.
+ * This function is supposed to be called by the kernel in paths
+ * that do not allow sleeping. In this function we allow the counter
+ * to reach the ULLONG_MAX value, and we signal this as overflow
+ * condition by returining a POLLERR to poll(2).
+ */
+int eventfd_signal(struct file *file, int n)
+{
+ struct eventfd_ctx *ctx = file->private_data;
+ unsigned long flags;
+
+ if (n < 0)
+ return -EINVAL;
+ spin_lock_irqsave(&ctx->lock, flags);
+ if (ULLONG_MAX - ctx->count < n)
+ n = (int) (ULLONG_MAX - ctx->count);
+ ctx->count += n;
+ if (waitqueue_active(&ctx->wqh))
+ wake_up_locked(&ctx->wqh);
+ spin_unlock_irqrestore(&ctx->lock, flags);
+
+ return n;
+}
+
+static int eventfd_release(struct inode *inode, struct file *file)
+{
+ kfree(file->private_data);
+ return 0;
+}
+
+static unsigned int eventfd_poll(struct file *file, poll_table *wait)
+{
+ struct eventfd_ctx *ctx = file->private_data;
+ unsigned int events = 0;
+ unsigned long flags;
+
+ poll_wait(file, &ctx->wqh, wait);
+
+ spin_lock_irqsave(&ctx->lock, flags);
+ if (ctx->count > 0)
+ events |= POLLIN;
+ if (ctx->count == ULLONG_MAX)
+ events |= POLLERR;
+ if (ULLONG_MAX - 1 > ctx->count)
+ events |= POLLOUT;
+ spin_unlock_irqrestore(&ctx->lock, flags);
+
+ return events;
+}
+
+static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct eventfd_ctx *ctx = file->private_data;
+ ssize_t res;
+ __u64 ucnt;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (count < sizeof(ucnt))
+ return -EINVAL;
+ spin_lock_irq(&ctx->lock);
+ res = -EAGAIN;
+ ucnt = ctx->count;
+ if (ucnt > 0)
+ res = sizeof(ucnt);
+ else if (!(file->f_flags & O_NONBLOCK)) {
+ __add_wait_queue(&ctx->wqh, &wait);
+ for (res = 0;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (ctx->count > 0) {
+ ucnt = ctx->count;
+ res = sizeof(ucnt);
+ break;
+ }
+ if (signal_pending(current)) {
+ res = -ERESTARTSYS;
+ break;
+ }
+ spin_unlock_irq(&ctx->lock);
+ schedule();
+ spin_lock_irq(&ctx->lock);
+ }
+ __remove_wait_queue(&ctx->wqh, &wait);
+ __set_current_state(TASK_RUNNING);
+ }
+ if (res > 0) {
+ ctx->count = 0;
+ if (waitqueue_active(&ctx->wqh))
+ wake_up_locked(&ctx->wqh);
+ }
+ spin_unlock_irq(&ctx->lock);
+ if (res > 0 && put_user(ucnt, (__u64 __user *) buf))
+ return -EFAULT;
+
+ return res;
+}
+
+static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct eventfd_ctx *ctx = file->private_data;
+ ssize_t res;
+ __u64 ucnt;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (count < sizeof(ucnt))
+ return -EINVAL;
+ if (copy_from_user(&ucnt, buf, sizeof(ucnt)))
+ return -EFAULT;
+ if (ucnt == ULLONG_MAX)
+ return -EINVAL;
+ spin_lock_irq(&ctx->lock);
+ res = -EAGAIN;
+ if (ULLONG_MAX - ctx->count > ucnt)
+ res = sizeof(ucnt);
+ else if (!(file->f_flags & O_NONBLOCK)) {
+ __add_wait_queue(&ctx->wqh, &wait);
+ for (res = 0;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (ULLONG_MAX - ctx->count > ucnt) {
+ res = sizeof(ucnt);
+ break;
+ }
+ if (signal_pending(current)) {
+ res = -ERESTARTSYS;
+ break;
+ }
+ spin_unlock_irq(&ctx->lock);
+ schedule();
+ spin_lock_irq(&ctx->lock);
+ }
+ __remove_wait_queue(&ctx->wqh, &wait);
+ __set_current_state(TASK_RUNNING);
+ }
+ if (res > 0) {
+ ctx->count += ucnt;
+ if (waitqueue_active(&ctx->wqh))
+ wake_up_locked(&ctx->wqh);
+ }
+ spin_unlock_irq(&ctx->lock);
+
+ return res;
+}
+
+static const struct file_operations eventfd_fops = {
+ .release = eventfd_release,
+ .poll = eventfd_poll,
+ .read = eventfd_read,
+ .write = eventfd_write,
+};
+
+struct file *eventfd_fget(int fd)
+{
+ struct file *file;
+
+ file = fget(fd);
+ if (!file)
+ return ERR_PTR(-EBADF);
+ if (file->f_op != &eventfd_fops) {
+ fput(file);
+ return ERR_PTR(-EINVAL);
+ }
+
+ return file;
+}
+
+asmlinkage long sys_eventfd(unsigned int count)
+{
+ int error, fd;
+ struct eventfd_ctx *ctx;
+ struct file *file;
+ struct inode *inode;
+
+ ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ init_waitqueue_head(&ctx->wqh);
+ spin_lock_init(&ctx->lock);
+ ctx->count = count;
+
+ /*
+ * When we call this, the initialization must be complete, since
+ * anon_inode_getfd() will install the fd.
+ */
+ error = anon_inode_getfd(&fd, &inode, &file, "[eventfd]",
+ &eventfd_fops, ctx);
+ if (!error)
+ return fd;
+
+ kfree(ctx);
+ return error;
+}
+
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index b5c7ca58493..1aad34ea61a 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -11,7 +11,6 @@
*
*/
-#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -34,6 +33,7 @@
#include <linux/mount.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
+#include <linux/anon_inodes.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -41,7 +41,6 @@
#include <asm/atomic.h>
#include <asm/semaphore.h>
-
/*
* LOCKING:
* There are three level of locking required by epoll :
@@ -74,9 +73,6 @@
* a greater scalability.
*/
-
-#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
-
#define DEBUG_EPOLL 0
#if DEBUG_EPOLL > 0
@@ -106,7 +102,6 @@
#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event))
-
struct epoll_filefd {
struct file *file;
int fd;
@@ -224,43 +219,6 @@ struct ep_pqueue {
struct epitem *epi;
};
-
-
-static void ep_poll_safewake_init(struct poll_safewake *psw);
-static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
- struct eventpoll *ep);
-static int ep_alloc(struct eventpoll **pep);
-static void ep_free(struct eventpoll *ep);
-static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
-static void ep_use_epitem(struct epitem *epi);
-static void ep_release_epitem(struct epitem *epi);
-static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
- poll_table *pt);
-static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi);
-static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
- struct file *tfile, int fd);
-static int ep_modify(struct eventpoll *ep, struct epitem *epi,
- struct epoll_event *event);
-static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
-static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
-static int ep_remove(struct eventpoll *ep, struct epitem *epi);
-static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key);
-static int ep_eventpoll_close(struct inode *inode, struct file *file);
-static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
-static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
- struct epoll_event __user *events, int maxevents);
-static int ep_events_transfer(struct eventpoll *ep,
- struct epoll_event __user *events,
- int maxevents);
-static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
- int maxevents, long timeout);
-static int eventpollfs_delete_dentry(struct dentry *dentry);
-static struct inode *ep_eventpoll_inode(void);
-static int eventpollfs_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name,
- void *data, struct vfsmount *mnt);
-
/*
* This semaphore is used to serialize ep_free() and eventpoll_release_file().
*/
@@ -275,37 +233,6 @@ static struct kmem_cache *epi_cache __read_mostly;
/* Slab cache used to allocate "struct eppoll_entry" */
static struct kmem_cache *pwq_cache __read_mostly;
-/* Virtual fs used to allocate inodes for eventpoll files */
-static struct vfsmount *eventpoll_mnt __read_mostly;
-
-/* File callbacks that implement the eventpoll file behaviour */
-static const struct file_operations eventpoll_fops = {
- .release = ep_eventpoll_close,
- .poll = ep_eventpoll_poll
-};
-
-/*
- * This is used to register the virtual file system from where
- * eventpoll inodes are allocated.
- */
-static struct file_system_type eventpoll_fs_type = {
- .name = "eventpollfs",
- .get_sb = eventpollfs_get_sb,
- .kill_sb = kill_anon_super,
-};
-
-/* Very basic directory entry operations for the eventpoll virtual file system */
-static struct dentry_operations eventpollfs_dentry_operations = {
- .d_delete = eventpollfs_delete_dentry,
-};
-
-
-
-/* Fast test to see if the file is an evenpoll file */
-static inline int is_file_epoll(struct file *f)
-{
- return f->f_op == &eventpoll_fops;
-}
/* Setup the structure that is used as key for the rb-tree */
static inline void ep_set_ffd(struct epoll_filefd *ffd,
@@ -374,7 +301,6 @@ static void ep_poll_safewake_init(struct poll_safewake *psw)
spin_lock_init(&psw->lock);
}
-
/*
* Perform a safe wake up of the poll wait list. The problem is that
* with the new callback'd wake up system, it is possible that the
@@ -429,399 +355,144 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
spin_unlock_irqrestore(&psw->lock, flags);
}
-
/*
- * This is called from eventpoll_release() to unlink files from the eventpoll
- * interface. We need to have this facility to cleanup correctly files that are
- * closed without being removed from the eventpoll interface.
+ * This function unregister poll callbacks from the associated file descriptor.
+ * Since this must be called without holding "ep->lock" the atomic exchange trick
+ * will protect us from multiple unregister.
*/
-void eventpoll_release_file(struct file *file)
+static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
{
- struct list_head *lsthead = &file->f_ep_links;
- struct eventpoll *ep;
- struct epitem *epi;
+ int nwait;
+ struct list_head *lsthead = &epi->pwqlist;
+ struct eppoll_entry *pwq;
- /*
- * We don't want to get "file->f_ep_lock" because it is not
- * necessary. It is not necessary because we're in the "struct file"
- * cleanup path, and this means that noone is using this file anymore.
- * The only hit might come from ep_free() but by holding the semaphore
- * will correctly serialize the operation. We do need to acquire
- * "ep->sem" after "epmutex" because ep_remove() requires it when called
- * from anywhere but ep_free().
- */
- mutex_lock(&epmutex);
+ /* This is called without locks, so we need the atomic exchange */
+ nwait = xchg(&epi->nwait, 0);
- while (!list_empty(lsthead)) {
- epi = list_first_entry(lsthead, struct epitem, fllink);
+ if (nwait) {
+ while (!list_empty(lsthead)) {
+ pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
- ep = epi->ep;
- list_del_init(&epi->fllink);
- down_write(&ep->sem);
- ep_remove(ep, epi);
- up_write(&ep->sem);
+ list_del_init(&pwq->llink);
+ remove_wait_queue(pwq->whead, &pwq->wait);
+ kmem_cache_free(pwq_cache, pwq);
+ }
}
-
- mutex_unlock(&epmutex);
}
-
/*
- * It opens an eventpoll file descriptor by suggesting a storage of "size"
- * file descriptors. The size parameter is just an hint about how to size
- * data structures. It won't prevent the user to store more than "size"
- * file descriptors inside the epoll interface. It is the kernel part of
- * the userspace epoll_create(2).
+ * Unlink the "struct epitem" from all places it might have been hooked up.
+ * This function must be called with write IRQ lock on "ep->lock".
*/
-asmlinkage long sys_epoll_create(int size)
+static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
{
- int error, fd = -1;
- struct eventpoll *ep;
- struct inode *inode;
- struct file *file;
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
- current, size));
-
- /*
- * Sanity check on the size parameter, and create the internal data
- * structure ( "struct eventpoll" ).
- */
- error = -EINVAL;
- if (size <= 0 || (error = ep_alloc(&ep)) != 0)
- goto eexit_1;
+ int error;
/*
- * Creates all the items needed to setup an eventpoll file. That is,
- * a file structure, and inode and a free file descriptor.
+ * It can happen that this one is called for an item already unlinked.
+ * The check protect us from doing a double unlink ( crash ).
*/
- error = ep_getfd(&fd, &inode, &file, ep);
- if (error)
- goto eexit_2;
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
- current, size, fd));
-
- return fd;
-
-eexit_2:
- ep_free(ep);
- kfree(ep);
-eexit_1:
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
- current, size, error));
- return error;
-}
-
-
-/*
- * The following function implements the controller interface for
- * the eventpoll file that enables the insertion/removal/change of
- * file descriptors inside the interest set. It represents
- * the kernel part of the user space epoll_ctl(2).
- */
-asmlinkage long
-sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
-{
- int error;
- struct file *file, *tfile;
- struct eventpoll *ep;
- struct epitem *epi;
- struct epoll_event epds;
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p)\n",
- current, epfd, op, fd, event));
-
- error = -EFAULT;
- if (ep_op_has_event(op) &&
- copy_from_user(&epds, event, sizeof(struct epoll_event)))
- goto eexit_1;
-
- /* Get the "struct file *" for the eventpoll file */
- error = -EBADF;
- file = fget(epfd);
- if (!file)
- goto eexit_1;
-
- /* Get the "struct file *" for the target file */
- tfile = fget(fd);
- if (!tfile)
- goto eexit_2;
-
- /* The target file descriptor must support poll */
- error = -EPERM;
- if (!tfile->f_op || !tfile->f_op->poll)
- goto eexit_3;
+ error = -ENOENT;
+ if (!ep_rb_linked(&epi->rbn))
+ goto error_return;
/*
- * We have to check that the file structure underneath the file descriptor
- * the user passed to us _is_ an eventpoll file. And also we do not permit
- * adding an epoll file descriptor inside itself.
+ * Clear the event mask for the unlinked item. This will avoid item
+ * notifications to be sent after the unlink operation from inside
+ * the kernel->userspace event transfer loop.
*/
- error = -EINVAL;
- if (file == tfile || !is_file_epoll(file))
- goto eexit_3;
+ epi->event.events = 0;
/*
- * At this point it is safe to assume that the "private_data" contains
- * our own data structure.
+ * At this point is safe to do the job, unlink the item from our rb-tree.
+ * This operation togheter with the above check closes the door to
+ * double unlinks.
*/
- ep = file->private_data;
-
- down_write(&ep->sem);
-
- /* Try to lookup the file inside our RB tree */
- epi = ep_find(ep, tfile, fd);
-
- error = -EINVAL;
- switch (op) {
- case EPOLL_CTL_ADD:
- if (!epi) {
- epds.events |= POLLERR | POLLHUP;
-
- error = ep_insert(ep, &epds, tfile, fd);
- } else
- error = -EEXIST;
- break;
- case EPOLL_CTL_DEL:
- if (epi)
- error = ep_remove(ep, epi);
- else
- error = -ENOENT;
- break;
- case EPOLL_CTL_MOD:
- if (epi) {
- epds.events |= POLLERR | POLLHUP;
- error = ep_modify(ep, epi, &epds);
- } else
- error = -ENOENT;
- break;
- }
+ ep_rb_erase(&epi->rbn, &ep->rbr);
/*
- * The function ep_find() increments the usage count of the structure
- * so, if this is not NULL, we need to release it.
+ * If the item we are going to remove is inside the ready file descriptors
+ * we want to remove it from this list to avoid stale events.
*/
- if (epi)
- ep_release_epitem(epi);
+ if (ep_is_linked(&epi->rdllink))
+ list_del_init(&epi->rdllink);
- up_write(&ep->sem);
+ error = 0;
+error_return:
-eexit_3:
- fput(tfile);
-eexit_2:
- fput(file);
-eexit_1:
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p) = %d\n",
- current, epfd, op, fd, event, error));
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n",
+ current, ep, epi->ffd.file, error));
return error;
}
-
/*
- * Implement the event wait interface for the eventpoll file. It is the kernel
- * part of the user space epoll_wait(2).
+ * Increment the usage count of the "struct epitem" making it sure
+ * that the user will have a valid pointer to reference.
*/
-asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
- int maxevents, int timeout)
+static void ep_use_epitem(struct epitem *epi)
{
- int error;
- struct file *file;
- struct eventpoll *ep;
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n",
- current, epfd, events, maxevents, timeout));
-
- /* The maximum number of event must be greater than zero */
- if (maxevents <= 0 || maxevents > EP_MAX_EVENTS)
- return -EINVAL;
-
- /* Verify that the area passed by the user is writeable */
- if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) {
- error = -EFAULT;
- goto eexit_1;
- }
-
- /* Get the "struct file *" for the eventpoll file */
- error = -EBADF;
- file = fget(epfd);
- if (!file)
- goto eexit_1;
-
- /*
- * We have to check that the file structure underneath the fd
- * the user passed to us _is_ an eventpoll file.
- */
- error = -EINVAL;
- if (!is_file_epoll(file))
- goto eexit_2;
-
- /*
- * At this point it is safe to assume that the "private_data" contains
- * our own data structure.
- */
- ep = file->private_data;
-
- /* Time to fish for events ... */
- error = ep_poll(ep, events, maxevents, timeout);
-
-eexit_2:
- fput(file);
-eexit_1:
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d) = %d\n",
- current, epfd, events, maxevents, timeout, error));
-
- return error;
+ atomic_inc(&epi->usecnt);
}
-
-#ifdef TIF_RESTORE_SIGMASK
-
/*
- * Implement the event wait interface for the eventpoll file. It is the kernel
- * part of the user space epoll_pwait(2).
+ * Decrement ( release ) the usage count by signaling that the user
+ * has finished using the structure. It might lead to freeing the
+ * structure itself if the count goes to zero.
*/
-asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
- int maxevents, int timeout, const sigset_t __user *sigmask,
- size_t sigsetsize)
+static void ep_release_epitem(struct epitem *epi)
{
- int error;
- sigset_t ksigmask, sigsaved;
-
- /*
- * If the caller wants a certain signal mask to be set during the wait,
- * we apply it here.
- */
- if (sigmask) {
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
- if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
- return -EFAULT;
- sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
- sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
- }
-
- error = sys_epoll_wait(epfd, events, maxevents, timeout);
-
- /*
- * If we changed the signal mask, we need to restore the original one.
- * In case we've got a signal while waiting, we do not restore the
- * signal mask yet, and we allow do_signal() to deliver the signal on
- * the way back to userspace, before the signal mask is restored.
- */
- if (sigmask) {
- if (error == -EINTR) {
- memcpy(&current->saved_sigmask, &sigsaved,
- sizeof(sigsaved));
- set_thread_flag(TIF_RESTORE_SIGMASK);
- } else
- sigprocmask(SIG_SETMASK, &sigsaved, NULL);
- }
-
- return error;
+ if (atomic_dec_and_test(&epi->usecnt))
+ kmem_cache_free(epi_cache, epi);
}
-#endif /* #ifdef TIF_RESTORE_SIGMASK */
-
-
/*
- * Creates the file descriptor to be used by the epoll interface.
+ * Removes a "struct epitem" from the eventpoll RB tree and deallocates
+ * all the associated resources.
*/
-static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
- struct eventpoll *ep)
+static int ep_remove(struct eventpoll *ep, struct epitem *epi)
{
- struct qstr this;
- char name[32];
- struct dentry *dentry;
- struct inode *inode;
- struct file *file;
- int error, fd;
-
- /* Get an ready to use file */
- error = -ENFILE;
- file = get_empty_filp();
- if (!file)
- goto eexit_1;
-
- /* Allocates an inode from the eventpoll file system */
- inode = ep_eventpoll_inode();
- if (IS_ERR(inode)) {
- error = PTR_ERR(inode);
- goto eexit_2;
- }
-
- /* Allocates a free descriptor to plug the file onto */
- error = get_unused_fd();
- if (error < 0)
- goto eexit_3;
- fd = error;
+ int error;
+ unsigned long flags;
+ struct file *file = epi->ffd.file;
/*
- * Link the inode to a directory entry by creating a unique name
- * using the inode number.
+ * Removes poll wait queue hooks. We _have_ to do this without holding
+ * the "ep->lock" otherwise a deadlock might occur. This because of the
+ * sequence of the lock acquisition. Here we do "ep->lock" then the wait
+ * queue head lock when unregistering the wait queue. The wakeup callback
+ * will run by holding the wait queue head lock and will call our callback
+ * that will try to get "ep->lock".
*/
- error = -ENOMEM;
- sprintf(name, "[%lu]", inode->i_ino);
- this.name = name;
- this.len = strlen(name);
- this.hash = inode->i_ino;
- dentry = d_alloc(eventpoll_mnt->mnt_sb->s_root, &this);
- if (!dentry)
- goto eexit_4;
- dentry->d_op = &eventpollfs_dentry_operations;
- d_add(dentry, inode);
- file->f_path.mnt = mntget(eventpoll_mnt);
- file->f_path.dentry = dentry;
- file->f_mapping = inode->i_mapping;
-
- file->f_pos = 0;
- file->f_flags = O_RDONLY;
- file->f_op = &eventpoll_fops;
- file->f_mode = FMODE_READ;
- file->f_version = 0;
- file->private_data = ep;
-
- /* Install the new setup file into the allocated fd. */
- fd_install(fd, file);
-
- *efd = fd;
- *einode = inode;
- *efile = file;
- return 0;
+ ep_unregister_pollwait(ep, epi);
-eexit_4:
- put_unused_fd(fd);
-eexit_3:
- iput(inode);
-eexit_2:
- put_filp(file);
-eexit_1:
- return error;
-}
+ /* Remove the current item from the list of epoll hooks */
+ spin_lock(&file->f_ep_lock);
+ if (ep_is_linked(&epi->fllink))
+ list_del_init(&epi->fllink);
+ spin_unlock(&file->f_ep_lock);
+ /* We need to acquire the write IRQ lock before calling ep_unlink() */
+ write_lock_irqsave(&ep->lock, flags);
-static int ep_alloc(struct eventpoll **pep)
-{
- struct eventpoll *ep = kzalloc(sizeof(*ep), GFP_KERNEL);
+ /* Really unlink the item from the RB tree */
+ error = ep_unlink(ep, epi);
- if (!ep)
- return -ENOMEM;
+ write_unlock_irqrestore(&ep->lock, flags);
- rwlock_init(&ep->lock);
- init_rwsem(&ep->sem);
- init_waitqueue_head(&ep->wq);
- init_waitqueue_head(&ep->poll_wait);
- INIT_LIST_HEAD(&ep->rdllist);
- ep->rbr = RB_ROOT;
+ if (error)
+ goto error_return;
- *pep = ep;
+ /* At this point it is safe to free the eventpoll item */
+ ep_release_epitem(epi);
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_alloc() ep=%p\n",
- current, ep));
- return 0;
-}
+ error = 0;
+error_return:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p) = %d\n",
+ current, ep, file, error));
+ return error;
+}
static void ep_free(struct eventpoll *ep)
{
@@ -865,6 +536,104 @@ static void ep_free(struct eventpoll *ep)
mutex_unlock(&epmutex);
}
+static int ep_eventpoll_release(struct inode *inode, struct file *file)
+{
+ struct eventpoll *ep = file->private_data;
+
+ if (ep) {
+ ep_free(ep);
+ kfree(ep);
+ }
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep));
+ return 0;
+}
+
+static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
+{
+ unsigned int pollflags = 0;
+ unsigned long flags;
+ struct eventpoll *ep = file->private_data;
+
+ /* Insert inside our poll wait queue */
+ poll_wait(file, &ep->poll_wait, wait);
+
+ /* Check our condition */
+ read_lock_irqsave(&ep->lock, flags);
+ if (!list_empty(&ep->rdllist))
+ pollflags = POLLIN | POLLRDNORM;
+ read_unlock_irqrestore(&ep->lock, flags);
+
+ return pollflags;
+}
+
+/* File callbacks that implement the eventpoll file behaviour */
+static const struct file_operations eventpoll_fops = {
+ .release = ep_eventpoll_release,
+ .poll = ep_eventpoll_poll
+};
+
+/* Fast test to see if the file is an evenpoll file */
+static inline int is_file_epoll(struct file *f)
+{
+ return f->f_op == &eventpoll_fops;
+}
+
+/*
+ * This is called from eventpoll_release() to unlink files from the eventpoll
+ * interface. We need to have this facility to cleanup correctly files that are
+ * closed without being removed from the eventpoll interface.
+ */
+void eventpoll_release_file(struct file *file)
+{
+ struct list_head *lsthead = &file->f_ep_links;
+ struct eventpoll *ep;
+ struct epitem *epi;
+
+ /*
+ * We don't want to get "file->f_ep_lock" because it is not
+ * necessary. It is not necessary because we're in the "struct file"
+ * cleanup path, and this means that noone is using this file anymore.
+ * The only hit might come from ep_free() but by holding the semaphore
+ * will correctly serialize the operation. We do need to acquire
+ * "ep->sem" after "epmutex" because ep_remove() requires it when called
+ * from anywhere but ep_free().
+ */
+ mutex_lock(&epmutex);
+
+ while (!list_empty(lsthead)) {
+ epi = list_first_entry(lsthead, struct epitem, fllink);
+
+ ep = epi->ep;
+ list_del_init(&epi->fllink);
+ down_write(&ep->sem);
+ ep_remove(ep, epi);
+ up_write(&ep->sem);
+ }
+
+ mutex_unlock(&epmutex);
+}
+
+static int ep_alloc(struct eventpoll **pep)
+{
+ struct eventpoll *ep = kzalloc(sizeof(*ep), GFP_KERNEL);
+
+ if (!ep)
+ return -ENOMEM;
+
+ rwlock_init(&ep->lock);
+ init_rwsem(&ep->sem);
+ init_waitqueue_head(&ep->wq);
+ init_waitqueue_head(&ep->poll_wait);
+ INIT_LIST_HEAD(&ep->rdllist);
+ ep->rbr = RB_ROOT;
+
+ *pep = ep;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_alloc() ep=%p\n",
+ current, ep));
+ return 0;
+}
/*
* Search the file inside the eventpoll tree. It add usage count to
@@ -902,30 +671,58 @@ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd)
return epir;
}
-
/*
- * Increment the usage count of the "struct epitem" making it sure
- * that the user will have a valid pointer to reference.
+ * This is the callback that is passed to the wait queue wakeup
+ * machanism. It is called by the stored file descriptors when they
+ * have events to report.
*/
-static void ep_use_epitem(struct epitem *epi)
+static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key)
{
+ int pwake = 0;
+ unsigned long flags;
+ struct epitem *epi = ep_item_from_wait(wait);
+ struct eventpoll *ep = epi->ep;
- atomic_inc(&epi->usecnt);
-}
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
+ current, epi->ffd.file, epi, ep));
+ write_lock_irqsave(&ep->lock, flags);
-/*
- * Decrement ( release ) the usage count by signaling that the user
- * has finished using the structure. It might lead to freeing the
- * structure itself if the count goes to zero.
- */
-static void ep_release_epitem(struct epitem *epi)
-{
+ /*
+ * If the event mask does not contain any poll(2) event, we consider the
+ * descriptor to be disabled. This condition is likely the effect of the
+ * EPOLLONESHOT bit that disables the descriptor when an event is received,
+ * until the next EPOLL_CTL_MOD will be issued.
+ */
+ if (!(epi->event.events & ~EP_PRIVATE_BITS))
+ goto is_disabled;
- if (atomic_dec_and_test(&epi->usecnt))
- kmem_cache_free(epi_cache, epi);
-}
+ /* If this file is already in the ready list we exit soon */
+ if (ep_is_linked(&epi->rdllink))
+ goto is_linked;
+ list_add_tail(&epi->rdllink, &ep->rdllist);
+
+is_linked:
+ /*
+ * Wake up ( if active ) both the eventpoll wait list and the ->poll()
+ * wait list.
+ */
+ if (waitqueue_active(&ep->wq))
+ __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE |
+ TASK_INTERRUPTIBLE);
+ if (waitqueue_active(&ep->poll_wait))
+ pwake++;
+
+is_disabled:
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ /* We have to call this outside the lock */
+ if (pwake)
+ ep_poll_safewake(&psw, &ep->poll_wait);
+
+ return 1;
+}
/*
* This is the callback that is used to add our wait queue to the
@@ -950,7 +747,6 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
}
}
-
static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
{
int kcmp;
@@ -970,7 +766,6 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
rb_insert_color(&epi->rbn, &ep->rbr);
}
-
static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
struct file *tfile, int fd)
{
@@ -981,7 +776,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
error = -ENOMEM;
if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL)))
- goto eexit_1;
+ goto error_return;
/* Item initialization follow here ... */
ep_rb_initnode(&epi->rbn);
@@ -1011,7 +806,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
* high memory pressure.
*/
if (epi->nwait < 0)
- goto eexit_2;
+ goto error_unregister;
/* Add the current item to the list of active epoll hook for this file */
spin_lock(&tfile->f_ep_lock);
@@ -1046,7 +841,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
return 0;
-eexit_2:
+error_unregister:
ep_unregister_pollwait(ep, epi);
/*
@@ -1059,11 +854,10 @@ eexit_2:
write_unlock_irqrestore(&ep->lock, flags);
kmem_cache_free(epi_cache, epi);
-eexit_1:
+error_return:
return error;
}
-
/*
* Modify the interest event mask by dropping an event if the new mask
* has a match in the current file status.
@@ -1126,216 +920,6 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
return 0;
}
-
-/*
- * This function unregister poll callbacks from the associated file descriptor.
- * Since this must be called without holding "ep->lock" the atomic exchange trick
- * will protect us from multiple unregister.
- */
-static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
-{
- int nwait;
- struct list_head *lsthead = &epi->pwqlist;
- struct eppoll_entry *pwq;
-
- /* This is called without locks, so we need the atomic exchange */
- nwait = xchg(&epi->nwait, 0);
-
- if (nwait) {
- while (!list_empty(lsthead)) {
- pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
-
- list_del_init(&pwq->llink);
- remove_wait_queue(pwq->whead, &pwq->wait);
- kmem_cache_free(pwq_cache, pwq);
- }
- }
-}
-
-
-/*
- * Unlink the "struct epitem" from all places it might have been hooked up.
- * This function must be called with write IRQ lock on "ep->lock".
- */
-static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
-{
- int error;
-
- /*
- * It can happen that this one is called for an item already unlinked.
- * The check protect us from doing a double unlink ( crash ).
- */
- error = -ENOENT;
- if (!ep_rb_linked(&epi->rbn))
- goto eexit_1;
-
- /*
- * Clear the event mask for the unlinked item. This will avoid item
- * notifications to be sent after the unlink operation from inside
- * the kernel->userspace event transfer loop.
- */
- epi->event.events = 0;
-
- /*
- * At this point is safe to do the job, unlink the item from our rb-tree.
- * This operation togheter with the above check closes the door to
- * double unlinks.
- */
- ep_rb_erase(&epi->rbn, &ep->rbr);
-
- /*
- * If the item we are going to remove is inside the ready file descriptors
- * we want to remove it from this list to avoid stale events.
- */
- if (ep_is_linked(&epi->rdllink))
- list_del_init(&epi->rdllink);
-
- error = 0;
-eexit_1:
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n",
- current, ep, epi->ffd.file, error));
-
- return error;
-}
-
-
-/*
- * Removes a "struct epitem" from the eventpoll RB tree and deallocates
- * all the associated resources.
- */
-static int ep_remove(struct eventpoll *ep, struct epitem *epi)
-{
- int error;
- unsigned long flags;
- struct file *file = epi->ffd.file;
-
- /*
- * Removes poll wait queue hooks. We _have_ to do this without holding
- * the "ep->lock" otherwise a deadlock might occur. This because of the
- * sequence of the lock acquisition. Here we do "ep->lock" then the wait
- * queue head lock when unregistering the wait queue. The wakeup callback
- * will run by holding the wait queue head lock and will call our callback
- * that will try to get "ep->lock".
- */
- ep_unregister_pollwait(ep, epi);
-
- /* Remove the current item from the list of epoll hooks */
- spin_lock(&file->f_ep_lock);
- if (ep_is_linked(&epi->fllink))
- list_del_init(&epi->fllink);
- spin_unlock(&file->f_ep_lock);
-
- /* We need to acquire the write IRQ lock before calling ep_unlink() */
- write_lock_irqsave(&ep->lock, flags);
-
- /* Really unlink the item from the RB tree */
- error = ep_unlink(ep, epi);
-
- write_unlock_irqrestore(&ep->lock, flags);
-
- if (error)
- goto eexit_1;
-
- /* At this point it is safe to free the eventpoll item */
- ep_release_epitem(epi);
-
- error = 0;
-eexit_1:
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p) = %d\n",
- current, ep, file, error));
-
- return error;
-}
-
-
-/*
- * This is the callback that is passed to the wait queue wakeup
- * machanism. It is called by the stored file descriptors when they
- * have events to report.
- */
-static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key)
-{
- int pwake = 0;
- unsigned long flags;
- struct epitem *epi = ep_item_from_wait(wait);
- struct eventpoll *ep = epi->ep;
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
- current, epi->ffd.file, epi, ep));
-
- write_lock_irqsave(&ep->lock, flags);
-
- /*
- * If the event mask does not contain any poll(2) event, we consider the
- * descriptor to be disabled. This condition is likely the effect of the
- * EPOLLONESHOT bit that disables the descriptor when an event is received,
- * until the next EPOLL_CTL_MOD will be issued.
- */
- if (!(epi->event.events & ~EP_PRIVATE_BITS))
- goto is_disabled;
-
- /* If this file is already in the ready list we exit soon */
- if (ep_is_linked(&epi->rdllink))
- goto is_linked;
-
- list_add_tail(&epi->rdllink, &ep->rdllist);
-
-is_linked:
- /*
- * Wake up ( if active ) both the eventpoll wait list and the ->poll()
- * wait list.
- */
- if (waitqueue_active(&ep->wq))
- __wake_up_locked(&ep->wq, TASK_UNINTERRUPTIBLE |
- TASK_INTERRUPTIBLE);
- if (waitqueue_active(&ep->poll_wait))
- pwake++;
-
-is_disabled:
- write_unlock_irqrestore(&ep->lock, flags);
-
- /* We have to call this outside the lock */
- if (pwake)
- ep_poll_safewake(&psw, &ep->poll_wait);
-
- return 1;
-}
-
-
-static int ep_eventpoll_close(struct inode *inode, struct file *file)
-{
- struct eventpoll *ep = file->private_data;
-
- if (ep) {
- ep_free(ep);
- kfree(ep);
- }
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep));
- return 0;
-}
-
-
-static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
-{
- unsigned int pollflags = 0;
- unsigned long flags;
- struct eventpoll *ep = file->private_data;
-
- /* Insert inside our poll wait queue */
- poll_wait(file, &ep->poll_wait, wait);
-
- /* Check our condition */
- read_lock_irqsave(&ep->lock, flags);
- if (!list_empty(&ep->rdllist))
- pollflags = POLLIN | POLLRDNORM;
- read_unlock_irqrestore(&ep->lock, flags);
-
- return pollflags;
-}
-
-
/*
* This function is called without holding the "ep->lock" since the call to
* __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ
@@ -1447,7 +1031,6 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
return eventcnt == 0 ? error: eventcnt;
}
-
/*
* Perform the transfer of events to user space.
*/
@@ -1483,7 +1066,6 @@ static int ep_events_transfer(struct eventpoll *ep,
return eventcnt;
}
-
static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
int maxevents, long timeout)
{
@@ -1553,52 +1135,262 @@ retry:
return res;
}
-static int eventpollfs_delete_dentry(struct dentry *dentry)
+/*
+ * It opens an eventpoll file descriptor by suggesting a storage of "size"
+ * file descriptors. The size parameter is just an hint about how to size
+ * data structures. It won't prevent the user to store more than "size"
+ * file descriptors inside the epoll interface. It is the kernel part of
+ * the userspace epoll_create(2).
+ */
+asmlinkage long sys_epoll_create(int size)
{
+ int error, fd = -1;
+ struct eventpoll *ep;
+ struct inode *inode;
+ struct file *file;
- return 1;
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
+ current, size));
+
+ /*
+ * Sanity check on the size parameter, and create the internal data
+ * structure ( "struct eventpoll" ).
+ */
+ error = -EINVAL;
+ if (size <= 0 || (error = ep_alloc(&ep)) != 0)
+ goto error_return;
+
+ /*
+ * Creates all the items needed to setup an eventpoll file. That is,
+ * a file structure, and inode and a free file descriptor.
+ */
+ error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]",
+ &eventpoll_fops, ep);
+ if (error)
+ goto error_free;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+ current, size, fd));
+
+ return fd;
+
+error_free:
+ ep_free(ep);
+ kfree(ep);
+error_return:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+ current, size, error));
+ return error;
}
-static struct inode *ep_eventpoll_inode(void)
+/*
+ * The following function implements the controller interface for
+ * the eventpoll file that enables the insertion/removal/change of
+ * file descriptors inside the interest set. It represents
+ * the kernel part of the user space epoll_ctl(2).
+ */
+asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
+ struct epoll_event __user *event)
{
- int error = -ENOMEM;
- struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
+ int error;
+ struct file *file, *tfile;
+ struct eventpoll *ep;
+ struct epitem *epi;
+ struct epoll_event epds;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p)\n",
+ current, epfd, op, fd, event));
+
+ error = -EFAULT;
+ if (ep_op_has_event(op) &&
+ copy_from_user(&epds, event, sizeof(struct epoll_event)))
+ goto error_return;
+
+ /* Get the "struct file *" for the eventpoll file */
+ error = -EBADF;
+ file = fget(epfd);
+ if (!file)
+ goto error_return;
+
+ /* Get the "struct file *" for the target file */
+ tfile = fget(fd);
+ if (!tfile)
+ goto error_fput;
+
+ /* The target file descriptor must support poll */
+ error = -EPERM;
+ if (!tfile->f_op || !tfile->f_op->poll)
+ goto error_tgt_fput;
+
+ /*
+ * We have to check that the file structure underneath the file descriptor
+ * the user passed to us _is_ an eventpoll file. And also we do not permit
+ * adding an epoll file descriptor inside itself.
+ */
+ error = -EINVAL;
+ if (file == tfile || !is_file_epoll(file))
+ goto error_tgt_fput;
- if (!inode)
- goto eexit_1;
+ /*
+ * At this point it is safe to assume that the "private_data" contains
+ * our own data structure.
+ */
+ ep = file->private_data;
+
+ down_write(&ep->sem);
- inode->i_fop = &eventpoll_fops;
+ /* Try to lookup the file inside our RB tree */
+ epi = ep_find(ep, tfile, fd);
+
+ error = -EINVAL;
+ switch (op) {
+ case EPOLL_CTL_ADD:
+ if (!epi) {
+ epds.events |= POLLERR | POLLHUP;
+ error = ep_insert(ep, &epds, tfile, fd);
+ } else
+ error = -EEXIST;
+ break;
+ case EPOLL_CTL_DEL:
+ if (epi)
+ error = ep_remove(ep, epi);
+ else
+ error = -ENOENT;
+ break;
+ case EPOLL_CTL_MOD:
+ if (epi) {
+ epds.events |= POLLERR | POLLHUP;
+ error = ep_modify(ep, epi, &epds);
+ } else
+ error = -ENOENT;
+ break;
+ }
/*
- * Mark the inode dirty from the very beginning,
- * that way it will never be moved to the dirty
- * list because mark_inode_dirty() will think
- * that it already _is_ on the dirty list.
+ * The function ep_find() increments the usage count of the structure
+ * so, if this is not NULL, we need to release it.
*/
- inode->i_state = I_DIRTY;
- inode->i_mode = S_IRUSR | S_IWUSR;
- inode->i_uid = current->fsuid;
- inode->i_gid = current->fsgid;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- return inode;
-
-eexit_1:
- return ERR_PTR(error);
+ if (epi)
+ ep_release_epitem(epi);
+ up_write(&ep->sem);
+
+error_tgt_fput:
+ fput(tfile);
+error_fput:
+ fput(file);
+error_return:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p) = %d\n",
+ current, epfd, op, fd, event, error));
+
+ return error;
}
-static int
-eventpollfs_get_sb(struct file_system_type *fs_type, int flags,
- const char *dev_name, void *data, struct vfsmount *mnt)
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_wait(2).
+ */
+asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
+ int maxevents, int timeout)
{
- return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC,
- mnt);
+ int error;
+ struct file *file;
+ struct eventpoll *ep;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n",
+ current, epfd, events, maxevents, timeout));
+
+ /* The maximum number of event must be greater than zero */
+ if (maxevents <= 0 || maxevents > EP_MAX_EVENTS)
+ return -EINVAL;
+
+ /* Verify that the area passed by the user is writeable */
+ if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) {
+ error = -EFAULT;
+ goto error_return;
+ }
+
+ /* Get the "struct file *" for the eventpoll file */
+ error = -EBADF;
+ file = fget(epfd);
+ if (!file)
+ goto error_return;
+
+ /*
+ * We have to check that the file structure underneath the fd
+ * the user passed to us _is_ an eventpoll file.
+ */
+ error = -EINVAL;
+ if (!is_file_epoll(file))
+ goto error_fput;
+
+ /*
+ * At this point it is safe to assume that the "private_data" contains
+ * our own data structure.
+ */
+ ep = file->private_data;
+
+ /* Time to fish for events ... */
+ error = ep_poll(ep, events, maxevents, timeout);
+
+error_fput:
+ fput(file);
+error_return:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d) = %d\n",
+ current, epfd, events, maxevents, timeout, error));
+
+ return error;
}
+#ifdef TIF_RESTORE_SIGMASK
-static int __init eventpoll_init(void)
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_pwait(2).
+ */
+asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
+ int maxevents, int timeout, const sigset_t __user *sigmask,
+ size_t sigsetsize)
{
int error;
+ sigset_t ksigmask, sigsaved;
+
+ /*
+ * If the caller wants a certain signal mask to be set during the wait,
+ * we apply it here.
+ */
+ if (sigmask) {
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+ if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
+ return -EFAULT;
+ sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
+ sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+ }
+
+ error = sys_epoll_wait(epfd, events, maxevents, timeout);
+
+ /*
+ * If we changed the signal mask, we need to restore the original one.
+ * In case we've got a signal while waiting, we do not restore the
+ * signal mask yet, and we allow do_signal() to deliver the signal on
+ * the way back to userspace, before the signal mask is restored.
+ */
+ if (sigmask) {
+ if (error == -EINTR) {
+ memcpy(&current->saved_sigmask, &sigsaved,
+ sizeof(sigsaved));
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ } else
+ sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+ }
+
+ return error;
+}
+#endif /* #ifdef TIF_RESTORE_SIGMASK */
+
+static int __init eventpoll_init(void)
+{
mutex_init(&epmutex);
/* Initialize the structure used to perform safe poll wait head wake ups */
@@ -1614,39 +1406,7 @@ static int __init eventpoll_init(void)
sizeof(struct eppoll_entry), 0,
EPI_SLAB_DEBUG|SLAB_PANIC, NULL, NULL);
- /*
- * Register the virtual file system that will be the source of inodes
- * for the eventpoll files
- */
- error = register_filesystem(&eventpoll_fs_type);
- if (error)
- goto epanic;
-
- /* Mount the above commented virtual file system */
- eventpoll_mnt = kern_mount(&eventpoll_fs_type);
- error = PTR_ERR(eventpoll_mnt);
- if (IS_ERR(eventpoll_mnt))
- goto epanic;
-
- DNPRINTK(3, (KERN_INFO "[%p] eventpoll: successfully initialized.\n",
- current));
return 0;
-
-epanic:
- panic("eventpoll_init() failed\n");
}
+fs_initcall(eventpoll_init);
-
-static void __exit eventpoll_exit(void)
-{
- /* Undo all operations done inside eventpoll_init() */
- unregister_filesystem(&eventpoll_fs_type);
- mntput(eventpoll_mnt);
- kmem_cache_destroy(pwq_cache);
- kmem_cache_destroy(epi_cache);
-}
-
-module_init(eventpoll_init);
-module_exit(eventpoll_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/fs/exec.c b/fs/exec.c
index 1ba85c7fc6a..70fa36554c1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -50,6 +50,7 @@
#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
#include <linux/audit.h>
+#include <linux/signalfd.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -582,6 +583,13 @@ static int de_thread(struct task_struct *tsk)
int count;
/*
+ * Tell all the sighand listeners that this sighand has
+ * been detached. The signalfd_detach() function grabs the
+ * sighand lock, if signal listeners are present on the sighand.
+ */
+ signalfd_detach(tsk);
+
+ /*
* If we don't share sighandlers, then we aren't sharing anything
* and we can just re-use it all.
*/
@@ -702,7 +710,7 @@ static int de_thread(struct task_struct *tsk)
*/
detach_pid(tsk, PIDTYPE_PID);
tsk->pid = leader->pid;
- attach_pid(tsk, PIDTYPE_PID, tsk->pid);
+ attach_pid(tsk, PIDTYPE_PID, find_pid(tsk->pid));
transfer_pid(leader, tsk, PIDTYPE_PGID);
transfer_pid(leader, tsk, PIDTYPE_SID);
list_replace_rcu(&leader->tasks, &tsk->tasks);
@@ -757,8 +765,7 @@ no_thread_group:
spin_unlock(&oldsighand->siglock);
write_unlock_irq(&tasklist_lock);
- if (atomic_dec_and_test(&oldsighand->count))
- kmem_cache_free(sighand_cachep, oldsighand);
+ __cleanup_sighand(oldsighand);
}
BUG_ON(!thread_group_leader(tsk));
@@ -1488,6 +1495,8 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
int flag = 0;
int ispipe = 0;
+ audit_core_dumps(signr);
+
binfmt = current->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
diff --git a/fs/mpage.c b/fs/mpage.c
index 0fb914fc2ee..c1698f2291a 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -454,11 +454,18 @@ EXPORT_SYMBOL(mpage_readpage);
* written, so it can intelligently allocate a suitably-sized BIO. For now,
* just allocate full-size (16-page) BIOs.
*/
-static struct bio *
-__mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
- sector_t *last_block_in_bio, int *ret, struct writeback_control *wbc,
- writepage_t writepage_fn)
+struct mpage_data {
+ struct bio *bio;
+ sector_t last_block_in_bio;
+ get_block_t *get_block;
+ unsigned use_writepage;
+};
+
+static int __mpage_writepage(struct page *page, struct writeback_control *wbc,
+ void *data)
{
+ struct mpage_data *mpd = data;
+ struct bio *bio = mpd->bio;
struct address_space *mapping = page->mapping;
struct inode *inode = page->mapping->host;
const unsigned blkbits = inode->i_blkbits;
@@ -476,6 +483,7 @@ __mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
int length;
struct buffer_head map_bh;
loff_t i_size = i_size_read(inode);
+ int ret = 0;
if (page_has_buffers(page)) {
struct buffer_head *head = page_buffers(page);
@@ -538,7 +546,7 @@ __mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
map_bh.b_state = 0;
map_bh.b_size = 1 << blkbits;
- if (get_block(inode, block_in_file, &map_bh, 1))
+ if (mpd->get_block(inode, block_in_file, &map_bh, 1))
goto confused;
if (buffer_new(&map_bh))
unmap_underlying_metadata(map_bh.b_bdev,
@@ -584,7 +592,7 @@ page_is_mapped:
/*
* This page will go to BIO. Do we need to send this BIO off first?
*/
- if (bio && *last_block_in_bio != blocks[0] - 1)
+ if (bio && mpd->last_block_in_bio != blocks[0] - 1)
bio = mpage_bio_submit(WRITE, bio);
alloc_new:
@@ -641,7 +649,7 @@ alloc_new:
boundary_block, 1 << blkbits);
}
} else {
- *last_block_in_bio = blocks[blocks_per_page - 1];
+ mpd->last_block_in_bio = blocks[blocks_per_page - 1];
}
goto out;
@@ -649,18 +657,19 @@ confused:
if (bio)
bio = mpage_bio_submit(WRITE, bio);
- if (writepage_fn) {
- *ret = (*writepage_fn)(page, wbc);
+ if (mpd->use_writepage) {
+ ret = mapping->a_ops->writepage(page, wbc);
} else {
- *ret = -EAGAIN;
+ ret = -EAGAIN;
goto out;
}
/*
* The caller has a ref on the inode, so *mapping is stable
*/
- mapping_set_error(mapping, *ret);
+ mapping_set_error(mapping, ret);
out:
- return bio;
+ mpd->bio = bio;
+ return ret;
}
/**
@@ -683,120 +692,27 @@ out:
* the call was made get new I/O started against them. If wbc->sync_mode is
* WB_SYNC_ALL then we were called for data integrity and we must wait for
* existing IO to complete.
- *
- * If you fix this you should check generic_writepages() also!
*/
int
mpage_writepages(struct address_space *mapping,
struct writeback_control *wbc, get_block_t get_block)
{
- struct backing_dev_info *bdi = mapping->backing_dev_info;
- struct bio *bio = NULL;
- sector_t last_block_in_bio = 0;
- int ret = 0;
- int done = 0;
- int (*writepage)(struct page *page, struct writeback_control *wbc);
- struct pagevec pvec;
- int nr_pages;
- pgoff_t index;
- pgoff_t end; /* Inclusive */
- int scanned = 0;
- int range_whole = 0;
-
- if (wbc->nonblocking && bdi_write_congested(bdi)) {
- wbc->encountered_congestion = 1;
- return 0;
- }
-
- writepage = NULL;
- if (get_block == NULL)
- writepage = mapping->a_ops->writepage;
-
- pagevec_init(&pvec, 0);
- if (wbc->range_cyclic) {
- index = mapping->writeback_index; /* Start from prev offset */
- end = -1;
- } else {
- index = wbc->range_start >> PAGE_CACHE_SHIFT;
- end = wbc->range_end >> PAGE_CACHE_SHIFT;
- if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
- range_whole = 1;
- scanned = 1;
+ int ret;
+
+ if (!get_block)
+ ret = generic_writepages(mapping, wbc);
+ else {
+ struct mpage_data mpd = {
+ .bio = NULL,
+ .last_block_in_bio = 0,
+ .get_block = get_block,
+ .use_writepage = 1,
+ };
+
+ ret = write_cache_pages(mapping, wbc, __mpage_writepage, &mpd);
+ if (mpd.bio)
+ mpage_bio_submit(WRITE, mpd.bio);
}
-retry:
- while (!done && (index <= end) &&
- (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_DIRTY,
- min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
- unsigned i;
-
- scanned = 1;
- for (i = 0; i < nr_pages; i++) {
- struct page *page = pvec.pages[i];
-
- /*
- * At this point we hold neither mapping->tree_lock nor
- * lock on the page itself: the page may be truncated or
- * invalidated (changing page->mapping to NULL), or even
- * swizzled back from swapper_space to tmpfs file
- * mapping
- */
-
- lock_page(page);
-
- if (unlikely(page->mapping != mapping)) {
- unlock_page(page);
- continue;
- }
-
- if (!wbc->range_cyclic && page->index > end) {
- done = 1;
- unlock_page(page);
- continue;
- }
-
- if (wbc->sync_mode != WB_SYNC_NONE)
- wait_on_page_writeback(page);
-
- if (PageWriteback(page) ||
- !clear_page_dirty_for_io(page)) {
- unlock_page(page);
- continue;
- }
-
- if (writepage) {
- ret = (*writepage)(page, wbc);
- mapping_set_error(mapping, ret);
- } else {
- bio = __mpage_writepage(bio, page, get_block,
- &last_block_in_bio, &ret, wbc,
- page->mapping->a_ops->writepage);
- }
- if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
- unlock_page(page);
- if (ret || (--(wbc->nr_to_write) <= 0))
- done = 1;
- if (wbc->nonblocking && bdi_write_congested(bdi)) {
- wbc->encountered_congestion = 1;
- done = 1;
- }
- }
- pagevec_release(&pvec);
- cond_resched();
- }
- if (!scanned && !done) {
- /*
- * We hit the last page and there is more work to be done: wrap
- * back to the start of the file
- */
- scanned = 1;
- index = 0;
- goto retry;
- }
- if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
- mapping->writeback_index = index;
- if (bio)
- mpage_bio_submit(WRITE, bio);
return ret;
}
EXPORT_SYMBOL(mpage_writepages);
@@ -804,15 +720,15 @@ EXPORT_SYMBOL(mpage_writepages);
int mpage_writepage(struct page *page, get_block_t get_block,
struct writeback_control *wbc)
{
- int ret = 0;
- struct bio *bio;
- sector_t last_block_in_bio = 0;
-
- bio = __mpage_writepage(NULL, page, get_block,
- &last_block_in_bio, &ret, wbc, NULL);
- if (bio)
- mpage_bio_submit(WRITE, bio);
-
+ struct mpage_data mpd = {
+ .bio = NULL,
+ .last_block_in_bio = 0,
+ .get_block = get_block,
+ .use_writepage = 0,
+ };
+ int ret = __mpage_writepage(page, wbc, &mpd);
+ if (mpd.bio)
+ mpage_bio_submit(WRITE, mpd.bio);
return ret;
}
EXPORT_SYMBOL(mpage_writepage);
diff --git a/fs/namei.c b/fs/namei.c
index b3780e3fc88..5e2d98d10c5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1719,7 +1719,7 @@ do_last:
* It already exists.
*/
mutex_unlock(&dir->d_inode->i_mutex);
- audit_inode_update(path.dentry->d_inode);
+ audit_inode(pathname, path.dentry->d_inode);
error = -EEXIST;
if (flag & O_EXCL)
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 629e7abdd84..6e5c2534f4b 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -86,19 +86,15 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
}
/* Check for the current buffer head overflowing. */
if (unlikely(file_ofs + bh->b_size > init_size)) {
- u8 *kaddr;
int ofs;
ofs = 0;
if (file_ofs < init_size)
ofs = init_size - file_ofs;
local_irq_save(flags);
- kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);
- memset(kaddr + bh_offset(bh) + ofs, 0,
- bh->b_size - ofs);
- kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);
+ zero_user_page(page, bh_offset(bh) + ofs,
+ bh->b_size - ofs, KM_BIO_SRC_IRQ);
local_irq_restore(flags);
- flush_dcache_page(page);
}
} else {
clear_buffer_uptodate(bh);
@@ -245,8 +241,7 @@ static int ntfs_read_block(struct page *page)
rl = NULL;
nr = i = 0;
do {
- u8 *kaddr;
- int err;
+ int err = 0;
if (unlikely(buffer_uptodate(bh)))
continue;
@@ -254,7 +249,6 @@ static int ntfs_read_block(struct page *page)
arr[nr++] = bh;
continue;
}
- err = 0;
bh->b_bdev = vol->sb->s_bdev;
/* Is the block within the allowed limits? */
if (iblock < lblock) {
@@ -340,10 +334,7 @@ handle_hole:
bh->b_blocknr = -1UL;
clear_buffer_mapped(bh);
handle_zblock:
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + i * blocksize, 0, blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, i * blocksize, blocksize, KM_USER0);
if (likely(!err))
set_buffer_uptodate(bh);
} while (i++, iblock++, (bh = bh->b_this_page) != head);
@@ -460,10 +451,7 @@ retry_readpage:
* ok to ignore the compressed flag here.
*/
if (unlikely(page->index > 0)) {
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr, 0, PAGE_CACHE_SIZE);
- flush_dcache_page(page);
- kunmap_atomic(kaddr, KM_USER0);
+ zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
goto done;
}
if (!NInoAttr(ni))
@@ -790,14 +778,10 @@ lock_retry_remap:
* uptodate so it can get discarded by the VM.
*/
if (err == -ENOENT || lcn == LCN_ENOENT) {
- u8 *kaddr;
-
bh->b_blocknr = -1;
clear_buffer_dirty(bh);
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + bh_offset(bh), 0, blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, bh_offset(bh), blocksize,
+ KM_USER0);
set_buffer_uptodate(bh);
err = 0;
continue;
@@ -1422,10 +1406,8 @@ retry_writepage:
if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) {
/* The page straddles i_size. */
unsigned int ofs = i_size & ~PAGE_CACHE_MASK;
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + ofs, 0, PAGE_CACHE_SIZE - ofs);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, ofs, PAGE_CACHE_SIZE - ofs,
+ KM_USER0);
}
/* Handle mst protected attributes. */
if (NInoMstProtected(ni))
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 621de369e6f..39a1669506b 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -606,11 +606,8 @@ do_next_page:
ntfs_submit_bh_for_read(bh);
*wait_bh++ = bh;
} else {
- u8 *kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + bh_offset(bh), 0,
- blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, bh_offset(bh),
+ blocksize, KM_USER0);
set_buffer_uptodate(bh);
}
}
@@ -685,12 +682,9 @@ map_buffer_cached:
ntfs_submit_bh_for_read(bh);
*wait_bh++ = bh;
} else {
- u8 *kaddr = kmap_atomic(page,
- KM_USER0);
- memset(kaddr + bh_offset(bh),
- 0, blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page,
+ bh_offset(bh),
+ blocksize, KM_USER0);
set_buffer_uptodate(bh);
}
}
@@ -708,11 +702,8 @@ map_buffer_cached:
*/
if (bh_end <= pos || bh_pos >= end) {
if (!buffer_uptodate(bh)) {
- u8 *kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + bh_offset(bh), 0,
- blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, bh_offset(bh),
+ blocksize, KM_USER0);
set_buffer_uptodate(bh);
}
mark_buffer_dirty(bh);
@@ -751,10 +742,8 @@ map_buffer_cached:
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh)) {
- u8 *kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + bh_offset(bh), 0, blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, bh_offset(bh), blocksize,
+ KM_USER0);
set_buffer_uptodate(bh);
}
continue;
@@ -878,11 +867,8 @@ rl_not_mapped_enoent:
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh)) {
- u8 *kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + bh_offset(bh), 0,
- blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, bh_offset(bh),
+ blocksize, KM_USER0);
set_buffer_uptodate(bh);
}
continue;
@@ -1137,16 +1123,12 @@ rl_not_mapped_enoent:
* to zero the overflowing region.
*/
if (unlikely(bh_pos + blocksize > initialized_size)) {
- u8 *kaddr;
int ofs = 0;
if (likely(bh_pos < initialized_size))
ofs = initialized_size - bh_pos;
- kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + bh_offset(bh) + ofs, 0,
- blocksize - ofs);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, bh_offset(bh) + ofs,
+ blocksize - ofs, KM_USER0);
}
} else /* if (unlikely(!buffer_uptodate(bh))) */
err = -EIO;
@@ -1286,11 +1268,8 @@ rl_not_mapped_enoent:
if (PageUptodate(page))
set_buffer_uptodate(bh);
else {
- u8 *kaddr = kmap_atomic(page, KM_USER0);
- memset(kaddr + bh_offset(bh), 0,
- blocksize);
- kunmap_atomic(kaddr, KM_USER0);
- flush_dcache_page(page);
+ zero_user_page(page, bh_offset(bh),
+ blocksize, KM_USER0);
set_buffer_uptodate(bh);
}
}
@@ -1350,9 +1329,7 @@ err_out:
len = PAGE_CACHE_SIZE;
if (len > bytes)
len = bytes;
- kaddr = kmap_atomic(*pages, KM_USER0);
- memset(kaddr, 0, len);
- kunmap_atomic(kaddr, KM_USER0);
+ zero_user_page(*pages, 0, len, KM_USER0);
}
goto out;
}
@@ -1473,9 +1450,7 @@ err_out:
len = PAGE_CACHE_SIZE;
if (len > bytes)
len = bytes;
- kaddr = kmap_atomic(*pages, KM_USER0);
- memset(kaddr, 0, len);
- kunmap_atomic(kaddr, KM_USER0);
+ zero_user_page(*pages, 0, len, KM_USER0);
}
goto out;
}
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index 01207042048..7638a1c42a7 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -239,7 +239,7 @@ config EFI_PARTITION
config SYSV68_PARTITION
bool "SYSV68 partition table support" if PARTITION_ADVANCED
- default y if M68K
+ default y if VME
help
Say Y here if you would like to be able to read the hard disk
partition table format used by Motorola Delta machines (using
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
index 1bea610078b..e7b07006bc4 100644
--- a/fs/partitions/efi.c
+++ b/fs/partitions/efi.c
@@ -152,7 +152,7 @@ last_lba(struct block_device *bdev)
}
static inline int
-pmbr_part_valid(struct partition *part, u64 lastlba)
+pmbr_part_valid(struct partition *part)
{
if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
le32_to_cpu(part->start_sect) == 1UL)
@@ -163,7 +163,6 @@ pmbr_part_valid(struct partition *part, u64 lastlba)
/**
* is_pmbr_valid(): test Protective MBR for validity
* @mbr: pointer to a legacy mbr structure
- * @lastlba: last_lba for the whole device
*
* Description: Returns 1 if PMBR is valid, 0 otherwise.
* Validity depends on two things:
@@ -171,13 +170,13 @@ pmbr_part_valid(struct partition *part, u64 lastlba)
* 2) One partition of type 0xEE is found
*/
static int
-is_pmbr_valid(legacy_mbr *mbr, u64 lastlba)
+is_pmbr_valid(legacy_mbr *mbr)
{
int i;
if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
return 0;
for (i = 0; i < 4; i++)
- if (pmbr_part_valid(&mbr->partition_record[i], lastlba))
+ if (pmbr_part_valid(&mbr->partition_record[i]))
return 1;
return 0;
}
@@ -516,7 +515,7 @@ find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
gpt_header *pgpt = NULL, *agpt = NULL;
gpt_entry *pptes = NULL, *aptes = NULL;
- legacy_mbr *legacymbr = NULL;
+ legacy_mbr *legacymbr;
u64 lastlba;
if (!bdev || !gpt || !ptes)
return 0;
@@ -528,9 +527,8 @@ find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
if (legacymbr) {
read_lba(bdev, 0, (u8 *) legacymbr,
sizeof (*legacymbr));
- good_pmbr = is_pmbr_valid(legacymbr, lastlba);
+ good_pmbr = is_pmbr_valid(legacymbr);
kfree(legacymbr);
- legacymbr=NULL;
}
if (!good_pmbr)
goto fail;
diff --git a/fs/signalfd.c b/fs/signalfd.c
new file mode 100644
index 00000000000..7cfeab412b4
--- /dev/null
+++ b/fs/signalfd.c
@@ -0,0 +1,349 @@
+/*
+ * fs/signalfd.c
+ *
+ * Copyright (C) 2003 Linus Torvalds
+ *
+ * Mon Mar 5, 2007: Davide Libenzi <davidel@xmailserver.org>
+ * Changed ->read() to return a siginfo strcture instead of signal number.
+ * Fixed locking in ->poll().
+ * Added sighand-detach notification.
+ * Added fd re-use in sys_signalfd() syscall.
+ * Now using anonymous inode source.
+ * Thanks to Oleg Nesterov for useful code review and suggestions.
+ * More comments and suggestions from Arnd Bergmann.
+ */
+
+#include <linux/file.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/list.h>
+#include <linux/anon_inodes.h>
+#include <linux/signalfd.h>
+
+struct signalfd_ctx {
+ struct list_head lnk;
+ wait_queue_head_t wqh;
+ sigset_t sigmask;
+ struct task_struct *tsk;
+};
+
+struct signalfd_lockctx {
+ struct task_struct *tsk;
+ unsigned long flags;
+};
+
+/*
+ * Tries to acquire the sighand lock. We do not increment the sighand
+ * use count, and we do not even pin the task struct, so we need to
+ * do it inside an RCU read lock, and we must be prepared for the
+ * ctx->tsk going to NULL (in signalfd_deliver()), and for the sighand
+ * being detached. We return 0 if the sighand has been detached, or
+ * 1 if we were able to pin the sighand lock.
+ */
+static int signalfd_lock(struct signalfd_ctx *ctx, struct signalfd_lockctx *lk)
+{
+ struct sighand_struct *sighand = NULL;
+
+ rcu_read_lock();
+ lk->tsk = rcu_dereference(ctx->tsk);
+ if (likely(lk->tsk != NULL))
+ sighand = lock_task_sighand(lk->tsk, &lk->flags);
+ rcu_read_unlock();
+
+ if (sighand && !ctx->tsk) {
+ unlock_task_sighand(lk->tsk, &lk->flags);
+ sighand = NULL;
+ }
+
+ return sighand != NULL;
+}
+
+static void signalfd_unlock(struct signalfd_lockctx *lk)
+{
+ unlock_task_sighand(lk->tsk, &lk->flags);
+}
+
+/*
+ * This must be called with the sighand lock held.
+ */
+void signalfd_deliver(struct task_struct *tsk, int sig)
+{
+ struct sighand_struct *sighand = tsk->sighand;
+ struct signalfd_ctx *ctx, *tmp;
+
+ BUG_ON(!sig);
+ list_for_each_entry_safe(ctx, tmp, &sighand->signalfd_list, lnk) {
+ /*
+ * We use a negative signal value as a way to broadcast that the
+ * sighand has been orphaned, so that we can notify all the
+ * listeners about this. Remember the ctx->sigmask is inverted,
+ * so if the user is interested in a signal, that corresponding
+ * bit will be zero.
+ */
+ if (sig < 0) {
+ if (ctx->tsk == tsk) {
+ ctx->tsk = NULL;
+ list_del_init(&ctx->lnk);
+ wake_up(&ctx->wqh);
+ }
+ } else {
+ if (!sigismember(&ctx->sigmask, sig))
+ wake_up(&ctx->wqh);
+ }
+ }
+}
+
+static void signalfd_cleanup(struct signalfd_ctx *ctx)
+{
+ struct signalfd_lockctx lk;
+
+ /*
+ * This is tricky. If the sighand is gone, we do not need to remove
+ * context from the list, the list itself won't be there anymore.
+ */
+ if (signalfd_lock(ctx, &lk)) {
+ list_del(&ctx->lnk);
+ signalfd_unlock(&lk);
+ }
+ kfree(ctx);
+}
+
+static int signalfd_release(struct inode *inode, struct file *file)
+{
+ signalfd_cleanup(file->private_data);
+ return 0;
+}
+
+static unsigned int signalfd_poll(struct file *file, poll_table *wait)
+{
+ struct signalfd_ctx *ctx = file->private_data;
+ unsigned int events = 0;
+ struct signalfd_lockctx lk;
+
+ poll_wait(file, &ctx->wqh, wait);
+
+ /*
+ * Let the caller get a POLLIN in this case, ala socket recv() when
+ * the peer disconnects.
+ */
+ if (signalfd_lock(ctx, &lk)) {
+ if (next_signal(&lk.tsk->pending, &ctx->sigmask) > 0 ||
+ next_signal(&lk.tsk->signal->shared_pending,
+ &ctx->sigmask) > 0)
+ events |= POLLIN;
+ signalfd_unlock(&lk);
+ } else
+ events |= POLLIN;
+
+ return events;
+}
+
+/*
+ * Copied from copy_siginfo_to_user() in kernel/signal.c
+ */
+static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
+ siginfo_t const *kinfo)
+{
+ long err;
+
+ BUILD_BUG_ON(sizeof(struct signalfd_siginfo) != 128);
+
+ /*
+ * Unused memebers should be zero ...
+ */
+ err = __clear_user(uinfo, sizeof(*uinfo));
+
+ /*
+ * If you change siginfo_t structure, please be sure
+ * this code is fixed accordingly.
+ */
+ err |= __put_user(kinfo->si_signo, &uinfo->signo);
+ err |= __put_user(kinfo->si_errno, &uinfo->err);
+ err |= __put_user((short)kinfo->si_code, &uinfo->code);
+ switch (kinfo->si_code & __SI_MASK) {
+ case __SI_KILL:
+ err |= __put_user(kinfo->si_pid, &uinfo->pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->uid);
+ break;
+ case __SI_TIMER:
+ err |= __put_user(kinfo->si_tid, &uinfo->tid);
+ err |= __put_user(kinfo->si_overrun, &uinfo->overrun);
+ err |= __put_user((long)kinfo->si_ptr, &uinfo->svptr);
+ break;
+ case __SI_POLL:
+ err |= __put_user(kinfo->si_band, &uinfo->band);
+ err |= __put_user(kinfo->si_fd, &uinfo->fd);
+ break;
+ case __SI_FAULT:
+ err |= __put_user((long)kinfo->si_addr, &uinfo->addr);
+#ifdef __ARCH_SI_TRAPNO
+ err |= __put_user(kinfo->si_trapno, &uinfo->trapno);
+#endif
+ break;
+ case __SI_CHLD:
+ err |= __put_user(kinfo->si_pid, &uinfo->pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->uid);
+ err |= __put_user(kinfo->si_status, &uinfo->status);
+ err |= __put_user(kinfo->si_utime, &uinfo->utime);
+ err |= __put_user(kinfo->si_stime, &uinfo->stime);
+ break;
+ case __SI_RT: /* This is not generated by the kernel as of now. */
+ case __SI_MESGQ: /* But this is */
+ err |= __put_user(kinfo->si_pid, &uinfo->pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->uid);
+ err |= __put_user((long)kinfo->si_ptr, &uinfo->svptr);
+ break;
+ default: /* this is just in case for now ... */
+ err |= __put_user(kinfo->si_pid, &uinfo->pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->uid);
+ break;
+ }
+
+ return err ? -EFAULT: sizeof(*uinfo);
+}
+
+/*
+ * Returns either the size of a "struct signalfd_siginfo", or zero if the
+ * sighand we are attached to, has been orphaned. The "count" parameter
+ * must be at least the size of a "struct signalfd_siginfo".
+ */
+static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct signalfd_ctx *ctx = file->private_data;
+ ssize_t res = 0;
+ int locked, signo;
+ siginfo_t info;
+ struct signalfd_lockctx lk;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (count < sizeof(struct signalfd_siginfo))
+ return -EINVAL;
+ locked = signalfd_lock(ctx, &lk);
+ if (!locked)
+ return 0;
+ res = -EAGAIN;
+ signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
+ if (signo == 0 && !(file->f_flags & O_NONBLOCK)) {
+ add_wait_queue(&ctx->wqh, &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
+ if (signo != 0)
+ break;
+ if (signal_pending(current)) {
+ res = -ERESTARTSYS;
+ break;
+ }
+ signalfd_unlock(&lk);
+ schedule();
+ locked = signalfd_lock(ctx, &lk);
+ if (unlikely(!locked)) {
+ /*
+ * Let the caller read zero byte, ala socket
+ * recv() when the peer disconnect. This test
+ * must be done before doing a dequeue_signal(),
+ * because if the sighand has been orphaned,
+ * the dequeue_signal() call is going to crash.
+ */
+ res = 0;
+ break;
+ }
+ }
+ remove_wait_queue(&ctx->wqh, &wait);
+ __set_current_state(TASK_RUNNING);
+ }
+ if (likely(locked))
+ signalfd_unlock(&lk);
+ if (likely(signo))
+ res = signalfd_copyinfo((struct signalfd_siginfo __user *) buf,
+ &info);
+
+ return res;
+}
+
+static const struct file_operations signalfd_fops = {
+ .release = signalfd_release,
+ .poll = signalfd_poll,
+ .read = signalfd_read,
+};
+
+/*
+ * Create a file descriptor that is associated with our signal
+ * state. We can pass it around to others if we want to, but
+ * it will always be _our_ signal state.
+ */
+asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask)
+{
+ int error;
+ sigset_t sigmask;
+ struct signalfd_ctx *ctx;
+ struct sighand_struct *sighand;
+ struct file *file;
+ struct inode *inode;
+ struct signalfd_lockctx lk;
+
+ if (sizemask != sizeof(sigset_t) ||
+ copy_from_user(&sigmask, user_mask, sizeof(sigmask)))
+ return error = -EINVAL;
+ sigdelsetmask(&sigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
+ signotset(&sigmask);
+
+ if (ufd == -1) {
+ ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ init_waitqueue_head(&ctx->wqh);
+ ctx->sigmask = sigmask;
+ ctx->tsk = current;
+
+ sighand = current->sighand;
+ /*
+ * Add this fd to the list of signal listeners.
+ */
+ spin_lock_irq(&sighand->siglock);
+ list_add_tail(&ctx->lnk, &sighand->signalfd_list);
+ spin_unlock_irq(&sighand->siglock);
+
+ /*
+ * When we call this, the initialization must be complete, since
+ * anon_inode_getfd() will install the fd.
+ */
+ error = anon_inode_getfd(&ufd, &inode, &file, "[signalfd]",
+ &signalfd_fops, ctx);
+ if (error)
+ goto err_fdalloc;
+ } else {
+ file = fget(ufd);
+ if (!file)
+ return -EBADF;
+ ctx = file->private_data;
+ if (file->f_op != &signalfd_fops) {
+ fput(file);
+ return -EINVAL;
+ }
+ /*
+ * We need to be prepared of the fact that the sighand this fd
+ * is attached to, has been detched. In that case signalfd_lock()
+ * will return 0, and we'll just skip setting the new mask.
+ */
+ if (signalfd_lock(ctx, &lk)) {
+ ctx->sigmask = sigmask;
+ signalfd_unlock(&lk);
+ }
+ wake_up(&ctx->wqh);
+ fput(file);
+ }
+
+ return ufd;
+
+err_fdalloc:
+ signalfd_cleanup(ctx);
+ return error;
+}
+
diff --git a/fs/timerfd.c b/fs/timerfd.c
new file mode 100644
index 00000000000..e329e37f15a
--- /dev/null
+++ b/fs/timerfd.c
@@ -0,0 +1,227 @@
+/*
+ * fs/timerfd.c
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ *
+ * Thanks to Thomas Gleixner for code reviews and useful comments.
+ *
+ */
+
+#include <linux/file.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <linux/anon_inodes.h>
+#include <linux/timerfd.h>
+
+struct timerfd_ctx {
+ struct hrtimer tmr;
+ ktime_t tintv;
+ spinlock_t lock;
+ wait_queue_head_t wqh;
+ int expired;
+};
+
+/*
+ * This gets called when the timer event triggers. We set the "expired"
+ * flag, but we do not re-arm the timer (in case it's necessary,
+ * tintv.tv64 != 0) until the timer is read.
+ */
+static enum hrtimer_restart timerfd_tmrproc(struct hrtimer *htmr)
+{
+ struct timerfd_ctx *ctx = container_of(htmr, struct timerfd_ctx, tmr);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->lock, flags);
+ ctx->expired = 1;
+ wake_up_locked(&ctx->wqh);
+ spin_unlock_irqrestore(&ctx->lock, flags);
+
+ return HRTIMER_NORESTART;
+}
+
+static void timerfd_setup(struct timerfd_ctx *ctx, int clockid, int flags,
+ const struct itimerspec *ktmr)
+{
+ enum hrtimer_mode htmode;
+ ktime_t texp;
+
+ htmode = (flags & TFD_TIMER_ABSTIME) ?
+ HRTIMER_MODE_ABS: HRTIMER_MODE_REL;
+
+ texp = timespec_to_ktime(ktmr->it_value);
+ ctx->expired = 0;
+ ctx->tintv = timespec_to_ktime(ktmr->it_interval);
+ hrtimer_init(&ctx->tmr, clockid, htmode);
+ ctx->tmr.expires = texp;
+ ctx->tmr.function = timerfd_tmrproc;
+ if (texp.tv64 != 0)
+ hrtimer_start(&ctx->tmr, texp, htmode);
+}
+
+static int timerfd_release(struct inode *inode, struct file *file)
+{
+ struct timerfd_ctx *ctx = file->private_data;
+
+ hrtimer_cancel(&ctx->tmr);
+ kfree(ctx);
+ return 0;
+}
+
+static unsigned int timerfd_poll(struct file *file, poll_table *wait)
+{
+ struct timerfd_ctx *ctx = file->private_data;
+ unsigned int events = 0;
+ unsigned long flags;
+
+ poll_wait(file, &ctx->wqh, wait);
+
+ spin_lock_irqsave(&ctx->lock, flags);
+ if (ctx->expired)
+ events |= POLLIN;
+ spin_unlock_irqrestore(&ctx->lock, flags);
+
+ return events;
+}
+
+static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ struct timerfd_ctx *ctx = file->private_data;
+ ssize_t res;
+ u32 ticks = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (count < sizeof(ticks))
+ return -EINVAL;
+ spin_lock_irq(&ctx->lock);
+ res = -EAGAIN;
+ if (!ctx->expired && !(file->f_flags & O_NONBLOCK)) {
+ __add_wait_queue(&ctx->wqh, &wait);
+ for (res = 0;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (ctx->expired) {
+ res = 0;
+ break;
+ }
+ if (signal_pending(current)) {
+ res = -ERESTARTSYS;
+ break;
+ }
+ spin_unlock_irq(&ctx->lock);
+ schedule();
+ spin_lock_irq(&ctx->lock);
+ }
+ __remove_wait_queue(&ctx->wqh, &wait);
+ __set_current_state(TASK_RUNNING);
+ }
+ if (ctx->expired) {
+ ctx->expired = 0;
+ if (ctx->tintv.tv64 != 0) {
+ /*
+ * If tintv.tv64 != 0, this is a periodic timer that
+ * needs to be re-armed. We avoid doing it in the timer
+ * callback to avoid DoS attacks specifying a very
+ * short timer period.
+ */
+ ticks = (u32)
+ hrtimer_forward(&ctx->tmr,
+ hrtimer_cb_get_time(&ctx->tmr),
+ ctx->tintv);
+ hrtimer_restart(&ctx->tmr);
+ } else
+ ticks = 1;
+ }
+ spin_unlock_irq(&ctx->lock);
+ if (ticks)
+ res = put_user(ticks, buf) ? -EFAULT: sizeof(ticks);
+ return res;
+}
+
+static const struct file_operations timerfd_fops = {
+ .release = timerfd_release,
+ .poll = timerfd_poll,
+ .read = timerfd_read,
+};
+
+asmlinkage long sys_timerfd(int ufd, int clockid, int flags,
+ const struct itimerspec __user *utmr)
+{
+ int error;
+ struct timerfd_ctx *ctx;
+ struct file *file;
+ struct inode *inode;
+ struct itimerspec ktmr;
+
+ if (copy_from_user(&ktmr, utmr, sizeof(ktmr)))
+ return -EFAULT;
+
+ if (clockid != CLOCK_MONOTONIC &&
+ clockid != CLOCK_REALTIME)
+ return -EINVAL;
+ if (!timespec_valid(&ktmr.it_value) ||
+ !timespec_valid(&ktmr.it_interval))
+ return -EINVAL;
+
+ if (ufd == -1) {
+ ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ init_waitqueue_head(&ctx->wqh);
+ spin_lock_init(&ctx->lock);
+
+ timerfd_setup(ctx, clockid, flags, &ktmr);
+
+ /*
+ * When we call this, the initialization must be complete, since
+ * anon_inode_getfd() will install the fd.
+ */
+ error = anon_inode_getfd(&ufd, &inode, &file, "[timerfd]",
+ &timerfd_fops, ctx);
+ if (error)
+ goto err_tmrcancel;
+ } else {
+ file = fget(ufd);
+ if (!file)
+ return -EBADF;
+ ctx = file->private_data;
+ if (file->f_op != &timerfd_fops) {
+ fput(file);
+ return -EINVAL;
+ }
+ /*
+ * We need to stop the existing timer before reprogramming
+ * it to the new values.
+ */
+ for (;;) {
+ spin_lock_irq(&ctx->lock);
+ if (hrtimer_try_to_cancel(&ctx->tmr) >= 0)
+ break;
+ spin_unlock_irq(&ctx->lock);
+ cpu_relax();
+ }
+ /*
+ * Re-program the timer to the new value ...
+ */
+ timerfd_setup(ctx, clockid, flags, &ktmr);
+
+ spin_unlock_irq(&ctx->lock);
+ fput(file);
+ }
+
+ return ufd;
+
+err_tmrcancel:
+ hrtimer_cancel(&ctx->tmr);
+ kfree(ctx);
+ return error;
+}
+
diff --git a/fs/xattr.c b/fs/xattr.c
index 9f4568b55b0..4523aca7965 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -350,6 +350,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
f = fget(fd);
if (!f)
return error;
+ audit_inode(NULL, f->f_path.dentry->d_inode);
error = getxattr(f->f_path.dentry, name, value, size);
fput(f);
return error;
@@ -422,6 +423,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
f = fget(fd);
if (!f)
return error;
+ audit_inode(NULL, f->f_path.dentry->d_inode);
error = listxattr(f->f_path.dentry, list, size);
fput(f);
return error;
diff --git a/include/asm-alpha/poll.h b/include/asm-alpha/poll.h
index 76f89356b6a..c98509d3149 100644
--- a/include/asm-alpha/poll.h
+++ b/include/asm-alpha/poll.h
@@ -1,25 +1 @@
-#ifndef __ALPHA_POLL_H
-#define __ALPHA_POLL_H
-
-#define POLLIN (1 << 0)
-#define POLLPRI (1 << 1)
-#define POLLOUT (1 << 2)
-#define POLLERR (1 << 3)
-#define POLLHUP (1 << 4)
-#define POLLNVAL (1 << 5)
-#define POLLRDNORM (1 << 6)
-#define POLLRDBAND (1 << 7)
-#define POLLWRNORM (1 << 8)
-#define POLLWRBAND (1 << 9)
-#define POLLMSG (1 << 10)
-#define POLLREMOVE (1 << 12)
-#define POLLRDHUP (1 << 13)
-
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif
+#include <asm-generic/poll.h>
diff --git a/include/asm-arm/poll.h b/include/asm-arm/poll.h
index 5030b2b232a..c98509d3149 100644
--- a/include/asm-arm/poll.h
+++ b/include/asm-arm/poll.h
@@ -1,27 +1 @@
-#ifndef __ASMARM_POLL_H
-#define __ASMARM_POLL_H
-
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif
+#include <asm-generic/poll.h>
diff --git a/include/asm-arm26/poll.h b/include/asm-arm26/poll.h
index 9ccb7f4190c..1170e7065f6 100644
--- a/include/asm-arm26/poll.h
+++ b/include/asm-arm26/poll.h
@@ -1,26 +1,8 @@
#ifndef __ASMARM_POLL_H
#define __ASMARM_POLL_H
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
+#include <asm-generic/poll.h>
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#undef POLLREMOVE
#endif
diff --git a/include/asm-avr32/poll.h b/include/asm-avr32/poll.h
index 736e29755df..c98509d3149 100644
--- a/include/asm-avr32/poll.h
+++ b/include/asm-avr32/poll.h
@@ -1,27 +1 @@
-#ifndef __ASM_AVR32_POLL_H
-#define __ASM_AVR32_POLL_H
-
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif /* __ASM_AVR32_POLL_H */
+#include <asm-generic/poll.h>
diff --git a/include/asm-cris/poll.h b/include/asm-cris/poll.h
index 1b25d4cf498..c98509d3149 100644
--- a/include/asm-cris/poll.h
+++ b/include/asm-cris/poll.h
@@ -1,26 +1 @@
-#ifndef __ASM_CRIS_POLL_H
-#define __ASM_CRIS_POLL_H
-
-/* taken from asm-alpha */
-
-#define POLLIN 1
-#define POLLPRI 2
-#define POLLOUT 4
-#define POLLERR 8
-#define POLLHUP 16
-#define POLLNVAL 32
-#define POLLRDNORM 64
-#define POLLRDBAND 128
-#define POLLWRNORM 256
-#define POLLWRBAND 512
-#define POLLMSG 1024
-#define POLLREMOVE 4096
-#define POLLRDHUP 8192
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif
+#include <asm-generic/poll.h>
diff --git a/include/asm-frv/poll.h b/include/asm-frv/poll.h
index c8fe8801d07..0d01479ccc5 100644
--- a/include/asm-frv/poll.h
+++ b/include/asm-frv/poll.h
@@ -1,24 +1,12 @@
#ifndef _ASM_POLL_H
#define _ASM_POLL_H
-#define POLLIN 1
-#define POLLPRI 2
-#define POLLOUT 4
-#define POLLERR 8
-#define POLLHUP 16
-#define POLLNVAL 32
-#define POLLRDNORM 64
#define POLLWRNORM POLLOUT
-#define POLLRDBAND 128
#define POLLWRBAND 256
-#define POLLMSG 0x0400
-#define POLLRDHUP 0x2000
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
+
+#undef POLLREMOVE
#endif
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index fa14f8cd30c..5bfeef76164 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -4,6 +4,7 @@ header-y += fcntl.h
header-y += ioctl.h
header-y += ipc.h
header-y += mman.h
+header-y += poll.h
header-y += signal.h
header-y += statfs.h
diff --git a/include/asm-generic/audit_signal.h b/include/asm-generic/audit_signal.h
new file mode 100644
index 00000000000..6feab7f18a5
--- /dev/null
+++ b/include/asm-generic/audit_signal.h
@@ -0,0 +1,3 @@
+__NR_kill,
+__NR_tgkill,
+__NR_tkill,
diff --git a/include/asm-generic/poll.h b/include/asm-generic/poll.h
new file mode 100644
index 00000000000..44bce836d35
--- /dev/null
+++ b/include/asm-generic/poll.h
@@ -0,0 +1,37 @@
+#ifndef __ASM_GENERIC_POLL_H
+#define __ASM_GENERIC_POLL_H
+
+/* These are specified by iBCS2 */
+#define POLLIN 0x0001
+#define POLLPRI 0x0002
+#define POLLOUT 0x0004
+#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
+
+/* The rest seem to be more-or-less nonstandard. Check them! */
+#define POLLRDNORM 0x0040
+#define POLLRDBAND 0x0080
+#ifndef POLLWRNORM
+#define POLLWRNORM 0x0100
+#endif
+#ifndef POLLWRBAND
+#define POLLWRBAND 0x0200
+#endif
+#ifndef POLLMSG
+#define POLLMSG 0x0400
+#endif
+#ifndef POLLREMOVE
+#define POLLREMOVE 0x1000
+#endif
+#ifndef POLLRDHUP
+#define POLLRDHUP 0x2000
+#endif
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#endif /* __ASM_GENERIC_POLL_H */
diff --git a/include/asm-h8300/poll.h b/include/asm-h8300/poll.h
index fc52103b276..f61540c22d9 100644
--- a/include/asm-h8300/poll.h
+++ b/include/asm-h8300/poll.h
@@ -1,23 +1,11 @@
#ifndef __H8300_POLL_H
#define __H8300_POLL_H
-#define POLLIN 1
-#define POLLPRI 2
-#define POLLOUT 4
-#define POLLERR 8
-#define POLLHUP 16
-#define POLLNVAL 32
-#define POLLRDNORM 64
#define POLLWRNORM POLLOUT
-#define POLLRDBAND 128
#define POLLWRBAND 256
-#define POLLMSG 0x0400
-#define POLLRDHUP 0x2000
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
+
+#undef POLLREMOVE
#endif
diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h
index 7ddd414f8d1..99f3c3561ec 100644
--- a/include/asm-h8300/unistd.h
+++ b/include/asm-h8300/unistd.h
@@ -21,7 +21,7 @@
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
-#define __NR_chown 16
+#define __NR_lchown 16
#define __NR_break 17
#define __NR_oldstat 18
#define __NR_lseek 19
@@ -115,10 +115,10 @@
#define __NR_lstat 107
#define __NR_fstat 108
#define __NR_olduname 109
-#define __NR_iopl /* 110 */ not supported
+#define __NR_iopl 110
#define __NR_vhangup 111
-#define __NR_idle /* 112 */ Obsolete
-#define __NR_vm86 /* 113 */ not supported
+#define __NR_idle 112
+#define __NR_vm86old 113
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
@@ -128,7 +128,7 @@
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
-#define __NR_cacheflush 123
+#define __NR_modify_ldt 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
@@ -171,7 +171,7 @@
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
-#define __NR_getpagesize 166
+#define __NR_vm86 166
#define __NR_query_module 167
#define __NR_poll 168
#define __NR_nfsservctl 169
@@ -187,7 +187,7 @@
#define __NR_rt_sigsuspend 179
#define __NR_pread64 180
#define __NR_pwrite64 181
-#define __NR_lchown 182
+#define __NR_chown 182
#define __NR_getcwd 183
#define __NR_capget 184
#define __NR_capset 185
@@ -203,7 +203,7 @@
#define __NR_stat64 195
#define __NR_lstat64 196
#define __NR_fstat64 197
-#define __NR_chown32 198
+#define __NR_lchown32 198
#define __NR_getuid32 199
#define __NR_getgid32 200
#define __NR_geteuid32 201
@@ -217,15 +217,18 @@
#define __NR_getresuid32 209
#define __NR_setresgid32 210
#define __NR_getresgid32 211
-#define __NR_lchown32 212
+#define __NR_chown32 212
#define __NR_setuid32 213
#define __NR_setgid32 214
#define __NR_setfsuid32 215
#define __NR_setfsgid32 216
#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+#define __NR_madvise1 219
#define __NR_getdents64 220
#define __NR_fcntl64 221
-#define __NR_security 223
+/* 223 is unused */
#define __NR_gettid 224
#define __NR_readahead 225
#define __NR_setxattr 226
@@ -252,13 +255,13 @@
#define __NR_io_getevents 247
#define __NR_io_submit 248
#define __NR_io_cancel 249
-#define __NR_alloc_hugepages 250
-#define __NR_free_hugepages 251
+#define __NR_fadvise64 250
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
#define __NR_exit_group 252
#define __NR_lookup_dcookie 253
-#define __NR_sys_epoll_create 254
-#define __NR_sys_epoll_ctl 255
-#define __NR_sys_epoll_wait 256
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
#define __NR_remap_file_pages 257
#define __NR_set_tid_address 258
#define __NR_timer_create 259
@@ -291,10 +294,41 @@
#define __NR_add_key 286
#define __NR_request_key 287
#define __NR_keyctl 288
+#define __NR_ioprio_set 289
+#define __NR_ioprio_get 290
+#define __NR_inotify_init 291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch 293
+#define __NR_migrate_pages 294
+#define __NR_openat 295
+#define __NR_mkdirat 296
+#define __NR_mknodat 297
+#define __NR_fchownat 298
+#define __NR_futimesat 299
+#define __NR_fstatat64 300
+#define __NR_unlinkat 301
+#define __NR_renameat 302
+#define __NR_linkat 303
+#define __NR_symlinkat 304
+#define __NR_readlinkat 305
+#define __NR_fchmodat 306
+#define __NR_faccessat 307
+#define __NR_pselect6 308
+#define __NR_ppoll 309
+#define __NR_unshare 310
+#define __NR_set_robust_list 311
+#define __NR_get_robust_list 312
+#define __NR_splice 313
+#define __NR_sync_file_range 314
+#define __NR_tee 315
+#define __NR_vmsplice 316
+#define __NR_move_pages 317
+#define __NR_getcpu 318
+#define __NR_epoll_pwait 319
#ifdef __KERNEL__
-#define NR_syscalls 289
+#define NR_syscalls 320
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h
index 0f70b379b02..eb7da5402bf 100644
--- a/include/asm-i386/alternative.h
+++ b/include/asm-i386/alternative.h
@@ -98,6 +98,12 @@ static inline void alternatives_smp_switch(int smp) {}
".previous" : output : [feat] "i" (feature), ##input)
/*
+ * use this macro(s) if you need more than one output parameter
+ * in alternative_io
+ */
+#define ASM_OUTPUT2(a, b) a, b
+
+/*
* Alternative inline assembly for SMP.
*
* The LOCK_PREFIX macro defined here replaces the LOCK and
diff --git a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h
index 47430175b75..d07b7afc269 100644
--- a/include/asm-i386/pgalloc.h
+++ b/include/asm-i386/pgalloc.h
@@ -65,6 +65,4 @@ do { \
#define pud_populate(mm, pmd, pte) BUG()
#endif
-#define check_pgt_cache() do { } while (0)
-
#endif /* _I386_PGALLOC_H */
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index edce9d51a67..2394589786b 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -35,17 +35,16 @@ struct vm_area_struct;
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
extern unsigned long empty_zero_page[1024];
extern pgd_t swapper_pg_dir[1024];
-extern struct kmem_cache *pgd_cache;
extern struct kmem_cache *pmd_cache;
extern spinlock_t pgd_lock;
extern struct page *pgd_list;
+void check_pgt_cache(void);
void pmd_ctor(void *, struct kmem_cache *, unsigned long);
-void pgd_ctor(void *, struct kmem_cache *, unsigned long);
-void pgd_dtor(void *, struct kmem_cache *, unsigned long);
void pgtable_cache_init(void);
void paging_init(void);
+
/*
* The Linux x86 paging architecture is 'compile-time dual-mode', it
* implements both the traditional 2-level x86 page tables and the
diff --git a/include/asm-i386/poll.h b/include/asm-i386/poll.h
index 2cd4929abd4..c98509d3149 100644
--- a/include/asm-i386/poll.h
+++ b/include/asm-i386/poll.h
@@ -1,27 +1 @@
-#ifndef __i386_POLL_H
-#define __i386_POLL_H
-
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif
+#include <asm-generic/poll.h>
diff --git a/include/asm-i386/tsc.h b/include/asm-i386/tsc.h
index 3f3c1fa000b..62c091ffccc 100644
--- a/include/asm-i386/tsc.h
+++ b/include/asm-i386/tsc.h
@@ -35,14 +35,16 @@ static inline cycles_t get_cycles(void)
static __always_inline cycles_t get_cycles_sync(void)
{
unsigned long long ret;
- unsigned eax;
+ unsigned eax, edx;
/*
* Use RDTSCP if possible; it is guaranteed to be synchronous
* and doesn't cause a VMEXIT on Hypervisors
*/
alternative_io(ASM_NOP3, ".byte 0x0f,0x01,0xf9", X86_FEATURE_RDTSCP,
- "=A" (ret), "0" (0ULL) : "ecx", "memory");
+ ASM_OUTPUT2("=a" (eax), "=d" (edx)),
+ "a" (0U), "d" (0U) : "ecx", "memory");
+ ret = (((unsigned long long)edx) << 32) | ((unsigned long long)eax);
if (ret)
return ret;
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index bd21e795197..e84ace1ec8b 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -326,10 +326,13 @@
#define __NR_getcpu 318
#define __NR_epoll_pwait 319
#define __NR_utimensat 320
+#define __NR_signalfd 321
+#define __NR_timerfd 322
+#define __NR_eventfd 323
#ifdef __KERNEL__
-#define NR_syscalls 321
+#define NR_syscalls 324
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index 79479e2c696..67221615e31 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -11,6 +11,9 @@
* 02/29/00 D.Mosberger moved most things into hw_irq.h
*/
+#include <linux/types.h>
+#include <linux/cpumask.h>
+
#define NR_IRQS 256
#define NR_IRQ_VECTORS NR_IRQS
@@ -29,5 +32,8 @@ extern void disable_irq (unsigned int);
extern void disable_irq_nosync (unsigned int);
extern void enable_irq (unsigned int);
extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
+bool is_affinity_mask_valid(cpumask_t cpumask);
+
+#define is_affinity_mask_valid is_affinity_mask_valid
#endif /* _ASM_IA64_IRQ_H */
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index 828ae00e47c..2abc98b336f 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -71,13 +71,15 @@ struct prev_kprobe {
#define MAX_PARAM_RSE_SIZE (0x60+0x60/0x3f)
/* per-cpu kprobe control block */
+#define ARCH_PREV_KPROBE_SZ 2
struct kprobe_ctlblk {
unsigned long kprobe_status;
struct pt_regs jprobe_saved_regs;
unsigned long jprobes_saved_stacked_regs[MAX_PARAM_RSE_SIZE];
unsigned long *bsp;
unsigned long cfm;
- struct prev_kprobe prev_kprobe;
+ atomic_t prev_kprobe_index;
+ struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ];
};
#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
diff --git a/include/asm-ia64/pgalloc.h b/include/asm-ia64/pgalloc.h
index 560c287b123..67552cad517 100644
--- a/include/asm-ia64/pgalloc.h
+++ b/include/asm-ia64/pgalloc.h
@@ -18,71 +18,18 @@
#include <linux/mm.h>
#include <linux/page-flags.h>
#include <linux/threads.h>
+#include <linux/quicklist.h>
#include <asm/mmu_context.h>
-DECLARE_PER_CPU(unsigned long *, __pgtable_quicklist);
-#define pgtable_quicklist __ia64_per_cpu_var(__pgtable_quicklist)
-DECLARE_PER_CPU(long, __pgtable_quicklist_size);
-#define pgtable_quicklist_size __ia64_per_cpu_var(__pgtable_quicklist_size)
-
-static inline long pgtable_quicklist_total_size(void)
-{
- long ql_size = 0;
- int cpuid;
-
- for_each_online_cpu(cpuid) {
- ql_size += per_cpu(__pgtable_quicklist_size, cpuid);
- }
- return ql_size;
-}
-
-static inline void *pgtable_quicklist_alloc(void)
-{
- unsigned long *ret = NULL;
-
- preempt_disable();
-
- ret = pgtable_quicklist;
- if (likely(ret != NULL)) {
- pgtable_quicklist = (unsigned long *)(*ret);
- ret[0] = 0;
- --pgtable_quicklist_size;
- preempt_enable();
- } else {
- preempt_enable();
- ret = (unsigned long *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
- }
-
- return ret;
-}
-
-static inline void pgtable_quicklist_free(void *pgtable_entry)
-{
-#ifdef CONFIG_NUMA
- int nid = page_to_nid(virt_to_page(pgtable_entry));
-
- if (unlikely(nid != numa_node_id())) {
- free_page((unsigned long)pgtable_entry);
- return;
- }
-#endif
-
- preempt_disable();
- *(unsigned long *)pgtable_entry = (unsigned long)pgtable_quicklist;
- pgtable_quicklist = (unsigned long *)pgtable_entry;
- ++pgtable_quicklist_size;
- preempt_enable();
-}
-
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
- return pgtable_quicklist_alloc();
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
}
static inline void pgd_free(pgd_t * pgd)
{
- pgtable_quicklist_free(pgd);
+ quicklist_free(0, NULL, pgd);
}
#ifdef CONFIG_PGTABLE_4
@@ -94,12 +41,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return pgtable_quicklist_alloc();
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
}
static inline void pud_free(pud_t * pud)
{
- pgtable_quicklist_free(pud);
+ quicklist_free(0, NULL, pud);
}
#define __pud_free_tlb(tlb, pud) pud_free(pud)
#endif /* CONFIG_PGTABLE_4 */
@@ -112,12 +59,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return pgtable_quicklist_alloc();
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
}
static inline void pmd_free(pmd_t * pmd)
{
- pgtable_quicklist_free(pmd);
+ quicklist_free(0, NULL, pmd);
}
#define __pmd_free_tlb(tlb, pmd) pmd_free(pmd)
@@ -137,28 +84,31 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long addr)
{
- void *pg = pgtable_quicklist_alloc();
+ void *pg = quicklist_alloc(0, GFP_KERNEL, NULL);
return pg ? virt_to_page(pg) : NULL;
}
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long addr)
{
- return pgtable_quicklist_alloc();
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
}
static inline void pte_free(struct page *pte)
{
- pgtable_quicklist_free(page_address(pte));
+ quicklist_free_page(0, NULL, pte);
}
static inline void pte_free_kernel(pte_t * pte)
{
- pgtable_quicklist_free(pte);
+ quicklist_free(0, NULL, pte);
}
-#define __pte_free_tlb(tlb, pte) pte_free(pte)
+static inline void check_pgt_cache(void)
+{
+ quicklist_trim(0, NULL, 25, 16);
+}
-extern void check_pgt_cache(void);
+#define __pte_free_tlb(tlb, pte) pte_free(pte)
#endif /* _ASM_IA64_PGALLOC_H */
diff --git a/include/asm-ia64/poll.h b/include/asm-ia64/poll.h
index bcaf9f14024..c98509d3149 100644
--- a/include/asm-ia64/poll.h
+++ b/include/asm-ia64/poll.h
@@ -1,32 +1 @@
-#ifndef _ASM_IA64_POLL_H
-#define _ASM_IA64_POLL_H
-
-/*
- * poll(2) bit definitions. Based on <asm-i386/poll.h>.
- *
- * Modified 1998, 1999, 2002
- * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif /* _ASM_IA64_POLL_H */
+#include <asm-generic/poll.h>
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 861c8ec87b0..f049bc40ca7 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -294,11 +294,13 @@
#define __NR_vmsplice 1302
/* 1303 reserved for move_pages */
#define __NR_getcpu 1304
+#define __NR_epoll_pwait 1305
+#define __NR_utimensat 1306
#ifdef __KERNEL__
-#define NR_syscalls 281 /* length of syscall table */
+#define NR_syscalls 283 /* length of syscall table */
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
diff --git a/include/asm-m32r/pgtable-2level.h b/include/asm-m32r/pgtable-2level.h
index 750925726a1..bca3475f959 100644
--- a/include/asm-m32r/pgtable-2level.h
+++ b/include/asm-m32r/pgtable-2level.h
@@ -71,8 +71,8 @@ static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address)
#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
#define PTE_FILE_MAX_BITS 29
-#define pte_to_pgoff(pte) (((pte_val(pte) >> 2) & 0xef) | (((pte_val(pte) >> 10)) << 7))
-#define pgoff_to_pte(off) ((pte_t) { (((off) & 0xef) << 2) | (((off) >> 7) << 10) | _PAGE_FILE })
+#define pte_to_pgoff(pte) (((pte_val(pte) >> 2) & 0x7f) | (((pte_val(pte) >> 10)) << 7))
+#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7f) << 2) | (((off) >> 7) << 10) | _PAGE_FILE })
#endif /* __KERNEL__ */
#endif /* _ASM_M32R_PGTABLE_2LEVEL_H */
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 8b2a2f17e69..6604303fc47 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -366,7 +366,7 @@ static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
#define pte_unmap_nested(pte) do { } while (0)
/* Encode and de-code a swap entry */
-#define __swp_type(x) (((x).val >> 2) & 0x3f)
+#define __swp_type(x) (((x).val >> 2) & 0x1f)
#define __swp_offset(x) ((x).val >> 10)
#define __swp_entry(type, offset) \
((swp_entry_t) { ((type) << 2) | ((offset) << 10) })
diff --git a/include/asm-m32r/poll.h b/include/asm-m32r/poll.h
index 9e0e700e727..c98509d3149 100644
--- a/include/asm-m32r/poll.h
+++ b/include/asm-m32r/poll.h
@@ -1,32 +1 @@
-#ifndef _ASM_M32R_POLL_H
-#define _ASM_M32R_POLL_H
-
-/*
- * poll(2) bit definitions. Based on <asm-i386/poll.h>.
- *
- * Modified 2004
- * Hirokazu Takata <takata at linux-m32r.org>
- */
-
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif /* _ASM_M32R_POLL_H */
+#include <asm-generic/poll.h>
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index f62f5c9abba..b291b2f7295 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -21,12 +21,22 @@
* `next' and `prev' should be struct task_struct, but it isn't always defined
*/
+#if defined(CONFIG_FRAME_POINTER) || \
+ !defined(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER)
+#define M32R_PUSH_FP " push fp\n"
+#define M32R_POP_FP " pop fp\n"
+#else
+#define M32R_PUSH_FP ""
+#define M32R_POP_FP ""
+#endif
+
#define switch_to(prev, next, last) do { \
__asm__ __volatile__ ( \
" seth lr, #high(1f) \n" \
" or3 lr, lr, #low(1f) \n" \
" st lr, @%4 ; store old LR \n" \
" ld lr, @%5 ; load new LR \n" \
+ M32R_PUSH_FP \
" st sp, @%2 ; store old SP \n" \
" ld sp, @%3 ; load new SP \n" \
" push %1 ; store `prev' on new stack \n" \
@@ -34,6 +44,7 @@
" .fillinsn \n" \
"1: \n" \
" pop %0 ; restore `__last' from new stack \n" \
+ M32R_POP_FP \
: "=r" (last) \
: "0" (prev), \
"r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \
diff --git a/include/asm-m68k/atarihw.h b/include/asm-m68k/atarihw.h
index 6211363a345..ecf007df774 100644
--- a/include/asm-m68k/atarihw.h
+++ b/include/asm-m68k/atarihw.h
@@ -2,7 +2,7 @@
** linux/atarihw.h -- This header defines some macros and pointers for
** the various Atari custom hardware registers.
**
-** Copyright 1994 by Bj”rn Brauel
+** Copyright 1994 by Björn Brauel
**
** 5/1/94 Roman Hodek:
** Added definitions for TT specific chips.
diff --git a/include/asm-m68k/atariints.h b/include/asm-m68k/atariints.h
index ce6c445805b..5748e99f4e2 100644
--- a/include/asm-m68k/atariints.h
+++ b/include/asm-m68k/atariints.h
@@ -1,7 +1,7 @@
/*
** atariints.h -- Atari Linux interrupt handling structs and prototypes
**
-** Copyright 1994 by Bj”rn Brauel
+** Copyright 1994 by Björn Brauel
**
** 5/2/94 Roman Hodek:
** TT interrupt definitions added.
diff --git a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h
index 0fb8843647f..f080fcdb61b 100644
--- a/include/asm-m68k/poll.h
+++ b/include/asm-m68k/poll.h
@@ -1,24 +1,9 @@
#ifndef __m68k_POLL_H
#define __m68k_POLL_H
-#define POLLIN 1
-#define POLLPRI 2
-#define POLLOUT 4
-#define POLLERR 8
-#define POLLHUP 16
-#define POLLNVAL 32
-#define POLLRDNORM 64
#define POLLWRNORM POLLOUT
-#define POLLRDBAND 128
#define POLLWRBAND 256
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
#endif
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 62daa746a9c..1b60624dab7 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -689,7 +689,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
}
#define atomic64_cmpxchg(v, o, n) \
- (((__typeof__((v)->counter)))cmpxchg(&((v)->counter), (o), (n)))
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
/**
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index dbf834f4dac..b0c329783ac 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -119,9 +119,9 @@
*/
#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */
#define MACH_MOMENCO_OCELOT 0
-#define MACH_MOMENCO_OCELOT_G 1
+#define MACH_MOMENCO_OCELOT_G 1 /* no more supported (may 2007) */
#define MACH_MOMENCO_OCELOT_C 2
-#define MACH_MOMENCO_JAGUAR_ATX 3
+#define MACH_MOMENCO_JAGUAR_ATX 3 /* no more supported (may 2007) */
#define MACH_MOMENCO_OCELOT_3 4
/*
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index b414a7d9db4..483685b1592 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -16,6 +16,7 @@
#include <asm/mipsregs.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
+#include <asm/hazards.h>
#include <asm/bitops.h>
#include <asm/processor.h>
#include <asm/current.h>
@@ -38,34 +39,16 @@ extern void _init_fpu(void);
extern void _save_fp(struct task_struct *);
extern void _restore_fp(struct task_struct *);
-#if defined(CONFIG_CPU_SB1)
-#define __enable_fpu_hazard() \
-do { \
- asm(".set push \n\t" \
- ".set mips64 \n\t" \
- ".set noreorder \n\t" \
- "ssnop \n\t" \
- "bnezl $0, .+4 \n\t" \
- "ssnop \n\t" \
- ".set pop"); \
-} while (0)
-#else
-#define __enable_fpu_hazard() \
-do { \
- asm("nop;nop;nop;nop"); /* max. hazard */ \
-} while (0)
-#endif
-
#define __enable_fpu() \
do { \
set_c0_status(ST0_CU1); \
- __enable_fpu_hazard(); \
+ enable_fpu_hazard(); \
} while (0)
#define __disable_fpu() \
do { \
clear_c0_status(ST0_CU1); \
- /* We don't care about the c0 hazard here */ \
+ disable_fpu_hazard(); \
} while (0)
#define enable_fpu() \
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
index e50c77e69cb..d9119f43f9a 100644
--- a/include/asm-mips/hazards.h
+++ b/include/asm-mips/hazards.h
@@ -178,4 +178,36 @@ ASMMACRO(back_to_back_c0_hazard,
#endif
+
+/* FPU hazards */
+
+#if defined(CONFIG_CPU_SB1)
+ASMMACRO(enable_fpu_hazard,
+ .set push;
+ .set mips64;
+ .set noreorder;
+ _ssnop;
+ bnezl $0,.+4;
+ _ssnop;
+ .set pop
+)
+ASMMACRO(disable_fpu_hazard,
+)
+
+#elif defined(CONFIG_CPU_MIPSR2)
+ASMMACRO(enable_fpu_hazard,
+ _ehb
+)
+ASMMACRO(disable_fpu_hazard,
+ _ehb
+)
+#else
+ASMMACRO(enable_fpu_hazard,
+ nop; nop; nop; nop
+)
+ASMMACRO(disable_fpu_hazard,
+ _ehb
+)
+#endif
+
#endif /* _ASM_HAZARDS_H */
diff --git a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h
index f8c8182f7f2..4d6bd5c31c7 100644
--- a/include/asm-mips/highmem.h
+++ b/include/asm-mips/highmem.h
@@ -48,46 +48,6 @@ extern pte_t *pkmap_page_table;
extern void * kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
-/*
- * CONFIG_LIMITED_DMA is for systems with DMA limitations such as Momentum's
- * Jaguar ATX. This option exploits the highmem code in the kernel so is
- * always enabled together with CONFIG_HIGHMEM but at this time doesn't
- * actually add highmem functionality.
- */
-
-#ifdef CONFIG_LIMITED_DMA
-
-/*
- * These are the default functions for the no-highmem case from
- * <linux/highmem.h>
- */
-static inline void *kmap(struct page *page)
-{
- might_sleep();
- return page_address(page);
-}
-
-#define kunmap(page) do { (void) (page); } while (0)
-
-static inline void *kmap_atomic(struct page *page, enum km_type type)
-{
- pagefault_disable();
- return page_address(page);
-}
-
-static inline void kunmap_atomic(void *kvaddr, enum km_type type)
-{
- pagefault_enable();
-}
-
-#define kmap_atomic_pfn(pfn, idx) kmap_atomic(pfn_to_page(pfn), (idx))
-
-#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
-
-#define flush_cache_kmaps() do { } while (0)
-
-#else /* LIMITED_DMA */
-
extern void *__kmap(struct page *page);
extern void __kunmap(struct page *page);
extern void *__kmap_atomic(struct page *page, enum km_type type);
@@ -103,8 +63,6 @@ extern struct page *__kmap_atomic_to_page(void *ptr);
#define flush_cache_kmaps() flush_cache_all()
-#endif /* LIMITED_DMA */
-
#endif /* __KERNEL__ */
#endif /* _ASM_HIGHMEM_H */
diff --git a/include/asm-mips/mach-cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h
index 24a8d51a55a..684a501c04c 100644
--- a/include/asm-mips/mach-cobalt/cobalt.h
+++ b/include/asm-mips/mach-cobalt/cobalt.h
@@ -69,6 +69,8 @@
#define COBALT_BRD_ID_QUBE2 0x5
#define COBALT_BRD_ID_RAQ2 0x6
+extern int cobalt_board_id;
+
#define PCI_CFG_SET(devfn,where) \
GT_WRITE(GT_PCI0_CFGADDR_OFS, (0x80000000 | (PCI_SLOT (devfn) << 11) | \
(PCI_FUNC (devfn) << 8) | (where)))
diff --git a/include/asm-mips/mach-ja/cpu-feature-overrides.h b/include/asm-mips/mach-ja/cpu-feature-overrides.h
deleted file mode 100644
index 84b6dead0e8..00000000000
--- a/include/asm-mips/mach-ja/cpu-feature-overrides.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2003, 2004 Ralf Baechle
- */
-#ifndef __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H
-
-/*
- * Momentum Jaguar ATX always has the RM9000 processor.
- */
-#define cpu_has_watch 1
-#define cpu_has_mips16 0
-#define cpu_has_divec 0
-#define cpu_has_vce 0
-#define cpu_has_cache_cdex_p 0
-#define cpu_has_cache_cdex_s 0
-#define cpu_has_prefetch 1
-#define cpu_has_mcheck 0
-#define cpu_has_ejtag 0
-
-#define cpu_has_llsc 1
-#define cpu_has_vtag_icache 0
-#define cpu_has_dc_aliases 0
-#define cpu_has_ic_fills_f_dc 0
-#define cpu_has_dsp 0
-#define cpu_icache_snoops_remote_store 0
-
-#define cpu_has_nofpuex 0
-#define cpu_has_64bits 1
-
-#define cpu_has_inclusive_pcaches 0
-
-#define cpu_dcache_line_size() 32
-#define cpu_icache_line_size() 32
-#define cpu_scache_line_size() 32
-
-#define cpu_has_mips32r1 0
-#define cpu_has_mips32r2 0
-#define cpu_has_mips64r1 0
-#define cpu_has_mips64r2 0
-
-#endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ja/spaces.h b/include/asm-mips/mach-ja/spaces.h
deleted file mode 100644
index 8466a0e69c7..00000000000
--- a/include/asm-mips/mach-ja/spaces.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
- * Copyright (C) 2000, 2002 Maciej W. Rozycki
- * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
- */
-#ifndef __ASM_MACH_JA_SPACES_H
-#define __ASM_MACH_JA_SPACES_H
-
-/*
- * Memory above this physical address will be considered highmem.
- */
-#define HIGHMEM_START 0x08000000UL
-
-#include_next <spaces.h>
-
-#endif /* __ASM_MACH_JA_SPACES_H */
diff --git a/include/asm-mips/mips-boards/malta.h b/include/asm-mips/mips-boards/malta.h
index b0ba3c5a921..eec91001bb6 100644
--- a/include/asm-mips/mips-boards/malta.h
+++ b/include/asm-mips/mips-boards/malta.h
@@ -25,6 +25,10 @@
#include <asm/mips-boards/msc01_pci.h>
#include <asm/gt64120.h>
+/* Mips interrupt controller found in SOCit variations */
+#define MIPS_MSC01_IC_REG_BASE 0x1bc40000
+#define MIPS_SOCITSC_IC_REG_BASE 0x1ffa0000
+
/*
* Malta I/O ports base address for the Galileo GT64120 and Algorithmics
* Bonito system controllers.
diff --git a/include/asm-mips/msc01_ic.h b/include/asm-mips/msc01_ic.h
index aa7ad9a7176..7989b9ffc1d 100644
--- a/include/asm-mips/msc01_ic.h
+++ b/include/asm-mips/msc01_ic.h
@@ -94,10 +94,7 @@
/*
* MIPS System controller interrupt register base.
*
- * FIXME - are these macros specific to Malta and co or to the MSC? If the
- * latter, they should be moved elsewhere.
*/
-#define MIPS_MSC01_IC_REG_BASE 0x1bc40000
/*****************************************************************************
* Absolute register addresses
@@ -144,7 +141,7 @@ typedef struct msc_irqmap {
#define MSC01_IRQ_LEVEL 0
#define MSC01_IRQ_EDGE 1
-extern void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq);
+extern void __init init_msc_irqs(unsigned long icubase, unsigned int base, msc_irqmap_t *imp, int nirq);
extern void ll_msc_irq(void);
#endif /* __ASM_MIPS_BOARDS_MSC01_IC_H */
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index d3fbd83ff54..5c3239dad0f 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -190,10 +190,6 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
-#ifdef CONFIG_LIMITED_DMA
-#define WANT_PAGE_VIRTUAL
-#endif
-
#include <asm-generic/memory_model.h>
#include <asm-generic/page.h>
diff --git a/include/asm-mips/poll.h b/include/asm-mips/poll.h
index 70881f8c5c5..47b95208043 100644
--- a/include/asm-mips/poll.h
+++ b/include/asm-mips/poll.h
@@ -1,28 +1,9 @@
#ifndef __ASM_POLL_H
#define __ASM_POLL_H
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
#define POLLWRNORM POLLOUT
#define POLLWRBAND 0x0100
-/* These seem to be more or less nonstandard ... */
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
#endif /* __ASM_POLL_H */
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index d7a65135d83..ce51213d84f 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -81,25 +81,6 @@
#define STD_SERIAL_PORT_DEFNS
#endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
-#ifdef CONFIG_MOMENCO_JAGUAR_ATX
-/* Ordinary NS16552 duart with a 20MHz crystal. */
-#define JAGUAR_ATX_UART_CLK 20000000
-#define JAGUAR_ATX_BASE_BAUD (JAGUAR_ATX_UART_CLK / 16)
-
-#define JAGUAR_ATX_SERIAL1_IRQ 6
-#define JAGUAR_ATX_SERIAL1_BASE 0xfd000023L
-
-#define _JAGUAR_ATX_SERIAL_INIT(int, base) \
- { .baud_base = JAGUAR_ATX_BASE_BAUD, irq: int, \
- .flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
- .iomem_base = (u8 *) base, iomem_reg_shift: 2, \
- io_type: SERIAL_IO_MEM }
-#define MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS \
- _JAGUAR_ATX_SERIAL_INIT(JAGUAR_ATX_SERIAL1_IRQ, JAGUAR_ATX_SERIAL1_BASE)
-#else
-#define MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS
-#endif
-
#ifdef CONFIG_MOMENCO_OCELOT_3
#define OCELOT_3_BASE_BAUD ( 20000000 / 16 )
#define OCELOT_3_SERIAL_IRQ 6
@@ -134,27 +115,6 @@
#define MOMENCO_OCELOT_SERIAL_PORT_DEFNS
#endif
-#ifdef CONFIG_MOMENCO_OCELOT_G
-/* Ordinary NS16552 duart with a 20MHz crystal. */
-#define OCELOT_G_BASE_BAUD ( 20000000 / 16 )
-
-#define OCELOT_G_SERIAL1_IRQ 4
-#if 0
-#define OCELOT_G_SERIAL1_BASE 0xe0001020
-#else
-#define OCELOT_G_SERIAL1_BASE 0xfd000020
-#endif
-
-#define _OCELOT_G_SERIAL_INIT(int, base) \
- { .baud_base = OCELOT_G_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS,\
- .iomem_base = (u8 *) base, .iomem_reg_shift = 2, \
- .io_type = SERIAL_IO_MEM }
-#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \
- _OCELOT_G_SERIAL_INIT(OCELOT_G_SERIAL1_IRQ, OCELOT_G_SERIAL1_BASE)
-#else
-#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS
-#endif
-
#ifdef CONFIG_MOMENCO_OCELOT_C
/* Ordinary NS16552 duart with a 20MHz crystal. */
#define OCELOT_C_BASE_BAUD ( 20000000 / 16 )
@@ -210,7 +170,6 @@
IP32_SERIAL_PORT_DEFNS \
JAZZ_SERIAL_PORT_DEFNS \
STD_SERIAL_PORT_DEFNS \
- MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \
MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \
MOMENCO_OCELOT_SERIAL_PORT_DEFNS \
MOMENCO_OCELOT_3_SERIAL_PORT_DEFNS
diff --git a/include/asm-mips/sgi/seeq.h b/include/asm-mips/sgi/seeq.h
new file mode 100644
index 00000000000..af0ffd76899
--- /dev/null
+++ b/include/asm-mips/sgi/seeq.h
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ */
+#ifndef __ASM_SGI_SEEQ_H
+#define __ASM_SGI_SEEQ_H
+
+#include <linux/if_ether.h>
+
+#include <asm/sgi/hpc3.h>
+
+struct sgiseeq_platform_data {
+ struct hpc3_regs *hpc;
+ unsigned int irq;
+ unsigned char mac[ETH_ALEN];
+};
+
+#endif /* __ASM_SGI_SEEQ_H */
diff --git a/include/asm-mips/sgi/wd.h b/include/asm-mips/sgi/wd.h
new file mode 100644
index 00000000000..0d6c3a4da89
--- /dev/null
+++ b/include/asm-mips/sgi/wd.h
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ */
+#ifndef __ASM_SGI_WD_H
+#define __ASM_SGI_WD_H
+
+#include <asm/sgi/hpc3.h>
+
+struct sgiwd93_platform_data {
+ unsigned int unit;
+ unsigned int irq;
+ struct hpc3_scsiregs *hregs;
+ unsigned char *wdregs;
+};
+
+#endif /* __ASM_SGI_WD_H */
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 3713d256d36..bb0b289dbc9 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -464,7 +464,10 @@ static inline unsigned long __cmpxchg_local(volatile void * ptr,
extern void set_handler (unsigned long offset, void *addr, unsigned long len);
extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
-extern void *set_vi_handler (int n, void *addr);
+
+typedef void (*vi_handler_t)(void);
+extern void *set_vi_handler (int n, vi_handler_t addr);
+
extern void *set_except_vector(int n, void *addr);
extern unsigned long ebase;
extern void per_cpu_trap_init(void);
diff --git a/include/asm-parisc/poll.h b/include/asm-parisc/poll.h
index 20e4d03c74c..c98509d3149 100644
--- a/include/asm-parisc/poll.h
+++ b/include/asm-parisc/poll.h
@@ -1,27 +1 @@
-#ifndef __PARISC_POLL_H
-#define __PARISC_POLL_H
-
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif
+#include <asm-generic/poll.h>
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
index 9e4dd98eb22..a7b60bf639e 100644
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -48,8 +48,15 @@ extern void iseries_handle_interrupts(void);
#define irqs_disabled() (local_get_flags() == 0)
-#define hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
-#define hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
+#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
+#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
+
+#define hard_irq_disable() \
+ do { \
+ __hard_irq_disable(); \
+ get_paca()->soft_enabled = 0; \
+ get_paca()->hard_enabled = 0; \
+ } while(0)
#else
diff --git a/include/asm-powerpc/poll.h b/include/asm-powerpc/poll.h
index 9c7d1263103..c98509d3149 100644
--- a/include/asm-powerpc/poll.h
+++ b/include/asm-powerpc/poll.h
@@ -1,24 +1 @@
-#ifndef _ASM_POWERPC_POLL_H
-#define _ASM_POWERPC_POLL_H
-
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif /* _ASM_POWERPC_POLL_H */
+#include <asm-generic/poll.h>
diff --git a/include/asm-s390/poll.h b/include/asm-s390/poll.h
index 6f7f65ac7d2..c98509d3149 100644
--- a/include/asm-s390/poll.h
+++ b/include/asm-s390/poll.h
@@ -1,35 +1 @@
-/*
- * include/asm-s390/poll.h
- *
- * S390 version
- *
- * Derived from "include/asm-i386/poll.h"
- */
-
-#ifndef __S390_POLL_H
-#define __S390_POLL_H
-
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif
+#include <asm-generic/poll.h>
diff --git a/include/asm-sh/poll.h b/include/asm-sh/poll.h
index dbca9b32f4a..c98509d3149 100644
--- a/include/asm-sh/poll.h
+++ b/include/asm-sh/poll.h
@@ -1,27 +1 @@
-#ifndef __ASM_SH_POLL_H
-#define __ASM_SH_POLL_H
-
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif /* __ASM_SH_POLL_H */
+#include <asm-generic/poll.h>
diff --git a/include/asm-sh64/poll.h b/include/asm-sh64/poll.h
index 3a6cbad08d2..ca2950267c5 100644
--- a/include/asm-sh64/poll.h
+++ b/include/asm-sh64/poll.h
@@ -1,37 +1,8 @@
#ifndef __ASM_SH64_POLL_H
#define __ASM_SH64_POLL_H
-/*
- * 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/asm-sh64/poll.h
- *
- * Copyright (C) 2000, 2001 Paolo Alberelli
- *
- */
+#include <asm-generic/poll.h>
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#undef POLLREMOVE
#endif /* __ASM_SH64_POLL_H */
diff --git a/include/asm-sparc/poll.h b/include/asm-sparc/poll.h
index 26f13fb3549..091d3ad2e83 100644
--- a/include/asm-sparc/poll.h
+++ b/include/asm-sparc/poll.h
@@ -1,24 +1,12 @@
#ifndef __SPARC_POLL_H
#define __SPARC_POLL_H
-#define POLLIN 1
-#define POLLPRI 2
-#define POLLOUT 4
-#define POLLERR 8
-#define POLLHUP 16
-#define POLLNVAL 32
-#define POLLRDNORM 64
#define POLLWRNORM POLLOUT
-#define POLLRDBAND 128
#define POLLWRBAND 256
#define POLLMSG 512
#define POLLREMOVE 1024
#define POLLRDHUP 2048
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
#endif
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index da9bdc5e552..64471bcd96f 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -327,8 +327,11 @@
#define __NR_getcpu 308
#define __NR_epoll_pwait 309
#define __NR_utimensat 310
+#define __NR_signalfd 311
+#define __NR_timerfd 312
+#define __NR_eventfd 313
-#define NR_SYSCALLS 311
+#define NR_SYSCALLS 314
#ifdef __KERNEL__
#define __ARCH_WANT_IPC_PARSE_VERSION
diff --git a/include/asm-sparc64/poll.h b/include/asm-sparc64/poll.h
index ab6b0d1bb4a..ebeeb3816c4 100644
--- a/include/asm-sparc64/poll.h
+++ b/include/asm-sparc64/poll.h
@@ -1,24 +1,12 @@
#ifndef __SPARC64_POLL_H
#define __SPARC64_POLL_H
-#define POLLIN 1
-#define POLLPRI 2
-#define POLLOUT 4
-#define POLLERR 8
-#define POLLHUP 16
-#define POLLNVAL 32
-#define POLLRDNORM 64
#define POLLWRNORM POLLOUT
-#define POLLRDBAND 128
#define POLLWRBAND 256
#define POLLMSG 512
#define POLLREMOVE 1024
#define POLLRDHUP 2048
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
#endif
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index fcd627594f4..53e96ed9c02 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -329,8 +329,11 @@
#define __NR_getcpu 308
#define __NR_epoll_pwait 309
#define __NR_utimensat 310
+#define __NR_signalfd 311
+#define __NR_timerfd 312
+#define __NR_eventfd 313
-#define NR_SYSCALLS 311
+#define NR_SYSCALLS 314
#ifdef __KERNEL__
/* sysconf options, for SunOS compatibility */
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index 261e2f4528f..18a13ba7460 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -22,6 +22,7 @@ struct thread_info {
0-0xBFFFFFFF for user
0-0xFFFFFFFF for kernel */
struct restart_block restart_block;
+ struct thread_info *real_thread; /* Points to non-IRQ stack */
};
#define INIT_THREAD_INFO(tsk) \
@@ -35,6 +36,7 @@ struct thread_info {
.restart_block = { \
.fn = do_no_restart_syscall, \
}, \
+ .real_thread = NULL, \
}
#define init_thread_info (init_thread_union.thread_info)
diff --git a/include/asm-v850/poll.h b/include/asm-v850/poll.h
index c10176c2c28..803cad0b9b5 100644
--- a/include/asm-v850/poll.h
+++ b/include/asm-v850/poll.h
@@ -1,24 +1,9 @@
#ifndef __V850_POLL_H__
#define __V850_POLL_H__
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-#define POLLRDNORM 0x0040
#define POLLWRNORM POLLOUT
-#define POLLRDBAND 0x0080
#define POLLWRBAND 0x0100
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
#endif /* __V850_POLL_H__ */
diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h
index a09fe85c268..a0942764076 100644
--- a/include/asm-x86_64/alternative.h
+++ b/include/asm-x86_64/alternative.h
@@ -103,6 +103,12 @@ static inline void alternatives_smp_switch(int smp) {}
".previous" : output : [feat] "i" (feature), ##input)
/*
+ * use this macro(s) if you need more than one output parameter
+ * in alternative_io
+ */
+#define ASM_OUTPUT2(a, b) a, b
+
+/*
* Alternative inline assembly for SMP.
*
* The LOCK_PREFIX macro defined here replaces the LOCK and
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index dee632fa457..e327c830da0 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -80,6 +80,15 @@ extern unsigned long phys_base;
#define __PHYSICAL_START CONFIG_PHYSICAL_START
#define __KERNEL_ALIGN 0x200000
+/*
+ * Make sure kernel is aligned to 2MB address. Catching it at compile
+ * time is better. Change your config file and compile the kernel
+ * for a 2MB aligned address (CONFIG_PHYSICAL_START)
+ */
+#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0
+#error "CONFIG_PHYSICAL_START must be a multiple of 2MB"
+#endif
+
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
#define __START_KERNEL_map _AC(0xffffffff80000000, UL)
#define __PAGE_OFFSET _AC(0xffff810000000000, UL)
diff --git a/include/asm-x86_64/poll.h b/include/asm-x86_64/poll.h
index c0475a9d8bb..c98509d3149 100644
--- a/include/asm-x86_64/poll.h
+++ b/include/asm-x86_64/poll.h
@@ -1,27 +1 @@
-#ifndef __x86_64_POLL_H
-#define __x86_64_POLL_H
-
-/* These are specified by iBCS2 */
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-/* The rest seem to be more-or-less nonstandard. Check them! */
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
-#define POLLWRNORM 0x0100
-#define POLLWRBAND 0x0200
-#define POLLMSG 0x0400
-#define POLLREMOVE 0x1000
-#define POLLRDHUP 0x2000
-
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
-
-#endif
+#include <asm-generic/poll.h>
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 595703949df..ae1ed05f281 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -621,6 +621,15 @@ __SYSCALL(__NR_vmsplice, sys_vmsplice)
__SYSCALL(__NR_move_pages, sys_move_pages)
#define __NR_utimensat 280
__SYSCALL(__NR_utimensat, sys_utimensat)
+#define __IGNORE_getcpu /* implemented as a vsyscall */
+#define __NR_epoll_pwait 281
+__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait)
+#define __NR_signalfd 282
+__SYSCALL(__NR_signalfd, sys_signalfd)
+#define __NR_timerfd 282
+__SYSCALL(__NR_timerfd, sys_timerfd)
+#define __NR_eventfd 283
+__SYSCALL(__NR_eventfd, sys_eventfd)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-xtensa/poll.h b/include/asm-xtensa/poll.h
index 6fd94773e86..9d2d5993f06 100644
--- a/include/asm-xtensa/poll.h
+++ b/include/asm-xtensa/poll.h
@@ -11,28 +11,10 @@
#ifndef _XTENSA_POLL_H
#define _XTENSA_POLL_H
-
-#define POLLIN 0x0001
-#define POLLPRI 0x0002
-#define POLLOUT 0x0004
-
-#define POLLERR 0x0008
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-#define POLLRDNORM 0x0040
-#define POLLRDBAND 0x0080
#define POLLWRNORM POLLOUT
#define POLLWRBAND 0x0100
-
-#define POLLMSG 0x0400
#define POLLREMOVE 0x0800
-#define POLLRDHUP 0x2000
-struct pollfd {
- int fd;
- short events;
- short revents;
-};
+#include <asm-generic/poll.h>
#endif /* _XTENSA_POLL_H */
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 94cc04a143f..bcd01f269f6 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -140,7 +140,6 @@ header-y += snmp.h
header-y += sockios.h
header-y += som.h
header-y += sound.h
-header-y += synclink.h
header-y += taskstats.h
header-y += telephony.h
header-y += termios.h
@@ -191,6 +190,7 @@ unifdef-y += errno.h
unifdef-y += errqueue.h
unifdef-y += ethtool.h
unifdef-y += eventpoll.h
+unifdef-y += signalfd.h
unifdef-y += ext2_fs.h
unifdef-y += ext3_fs.h
unifdef-y += fb.h
@@ -320,6 +320,7 @@ unifdef-y += sonypi.h
unifdef-y += soundcard.h
unifdef-y += stat.h
unifdef-y += stddef.h
+unifdef-y += synclink.h
unifdef-y += sysctl.h
unifdef-y += tcp.h
unifdef-y += time.h
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 43dc2ebfaa0..b903fc02bdb 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -119,6 +119,12 @@ struct kiocb {
struct list_head ki_list; /* the aio core uses this
* for cancellation */
+
+ /*
+ * If the aio_resfd field of the userspace iocb is not zero,
+ * this is the underlying file* to deliver event to.
+ */
+ struct file *ki_eventfd;
};
#define is_sync_kiocb(iocb) ((iocb)->ki_key == KIOCB_SYNC_KEY)
diff --git a/include/linux/aio_abi.h b/include/linux/aio_abi.h
index e3ca0a485cc..9e017293131 100644
--- a/include/linux/aio_abi.h
+++ b/include/linux/aio_abi.h
@@ -45,6 +45,14 @@ enum {
IOCB_CMD_PWRITEV = 8,
};
+/*
+ * Valid flags for the "aio_flags" member of the "struct iocb".
+ *
+ * IOCB_FLAG_RESFD - Set if the "aio_resfd" member of the "struct iocb"
+ * is valid.
+ */
+#define IOCB_FLAG_RESFD (1 << 0)
+
/* read() from /dev/aio returns these structures. */
struct io_event {
__u64 data; /* the data field from the iocb */
@@ -84,7 +92,15 @@ struct iocb {
/* extra parameters */
__u64 aio_reserved2; /* TODO: use this for a (struct sigevent *) */
- __u64 aio_reserved3;
+
+ /* flags for the "struct iocb" */
+ __u32 aio_flags;
+
+ /*
+ * if the IOCB_FLAG_RESFD flag of "aio_flags" is set, this is an
+ * eventfd to signal AIO readiness to
+ */
+ __u32 aio_resfd;
}; /* 64 bytes */
#undef IFBIG
diff --git a/include/linux/anon_inodes.h b/include/linux/anon_inodes.h
new file mode 100644
index 00000000000..b2e1ba325b9
--- /dev/null
+++ b/include/linux/anon_inodes.h
@@ -0,0 +1,16 @@
+/*
+ * include/linux/anon_inodes.h
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _LINUX_ANON_INODES_H
+#define _LINUX_ANON_INODES_H
+
+int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
+ const char *name, const struct file_operations *fops,
+ void *priv);
+
+#endif /* _LINUX_ANON_INODES_H */
+
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 773e30df11e..fccc6e50298 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -91,6 +91,7 @@
#define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */
#define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */
#define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */
+#define AUDIT_OBJ_PID 1318 /* ptrace target */
#define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
@@ -111,6 +112,7 @@
#define AUDIT_FIRST_KERN_ANOM_MSG 1700
#define AUDIT_LAST_KERN_ANOM_MSG 1799
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
+#define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
@@ -148,6 +150,8 @@
#define AUDIT_CLASS_READ_32 5
#define AUDIT_CLASS_WRITE 6
#define AUDIT_CLASS_WRITE_32 7
+#define AUDIT_CLASS_SIGNAL 8
+#define AUDIT_CLASS_SIGNAL_32 9
/* This bitmask is used to validate user input. It represents all bits that
* are currently used in an audit field constant understood by the kernel.
@@ -337,6 +341,7 @@ struct mqstat;
#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
extern int __init audit_register_class(int class, unsigned *list);
extern int audit_classify_syscall(int abi, unsigned syscall);
+extern int audit_classify_arch(int arch);
#ifdef CONFIG_AUDITSYSCALL
/* These are defined in auditsc.c */
/* Public API */
@@ -351,7 +356,8 @@ extern void audit_putname(const char *name);
extern void __audit_inode(const char *name, const struct inode *inode);
extern void __audit_inode_child(const char *dname, const struct inode *inode,
const struct inode *parent);
-extern void __audit_inode_update(const struct inode *inode);
+extern void __audit_ptrace(struct task_struct *t);
+
static inline int audit_dummy_context(void)
{
void *p = current->audit_context;
@@ -372,9 +378,12 @@ static inline void audit_inode_child(const char *dname,
if (unlikely(!audit_dummy_context()))
__audit_inode_child(dname, inode, parent);
}
-static inline void audit_inode_update(const struct inode *inode) {
+void audit_core_dumps(long signr);
+
+static inline void audit_ptrace(struct task_struct *t)
+{
if (unlikely(!audit_dummy_context()))
- __audit_inode_update(inode);
+ __audit_ptrace(t);
}
/* Private API (for audit.c only) */
@@ -447,6 +456,7 @@ static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
return 0;
}
extern int audit_n_rules;
+extern int audit_signals;
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
@@ -457,10 +467,9 @@ extern int audit_n_rules;
#define audit_putname(n) do { ; } while (0)
#define __audit_inode(n,i) do { ; } while (0)
#define __audit_inode_child(d,i,p) do { ; } while (0)
-#define __audit_inode_update(i) do { ; } while (0)
#define audit_inode(n,i) do { ; } while (0)
#define audit_inode_child(d,i,p) do { ; } while (0)
-#define audit_inode_update(i) do { ; } while (0)
+#define audit_core_dumps(i) do { ; } while (0)
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
#define audit_get_loginuid(c) ({ -1; })
#define audit_log_task_context(b) do { ; } while (0)
@@ -477,7 +486,9 @@ extern int audit_n_rules;
#define audit_mq_timedreceive(d,l,p,t) ({ 0; })
#define audit_mq_notify(d,n) ({ 0; })
#define audit_mq_getsetattr(d,s) ({ 0; })
+#define audit_ptrace(t) ((void)0)
#define audit_n_rules 0
+#define audit_signals 0
#endif
#ifdef CONFIG_AUDIT
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 70a157a130b..636502c0273 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -225,6 +225,11 @@ static inline int compat_timespec_compare(struct compat_timespec *lhs,
return lhs->tv_nsec - rhs->tv_nsec;
}
+extern int get_compat_itimerspec(struct itimerspec *dst,
+ const struct compat_itimerspec __user *src);
+extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
+ const struct itimerspec *src);
+
asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
extern int compat_printk(const char *fmt, ...);
diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
new file mode 100644
index 00000000000..0d6ecc60b94
--- /dev/null
+++ b/include/linux/eventfd.h
@@ -0,0 +1,29 @@
+/*
+ * include/linux/eventfd.h
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _LINUX_EVENTFD_H
+#define _LINUX_EVENTFD_H
+
+
+#ifdef __KERNEL__
+
+#ifdef CONFIG_EVENTFD
+
+struct file *eventfd_fget(int fd);
+int eventfd_signal(struct file *file, int n);
+
+#else /* CONFIG_EVENTFD */
+
+#define eventfd_fget(fd) ERR_PTR(-ENOSYS)
+#define eventfd_signal(f, n) 0
+
+#endif /* CONFIG_EVENTFD */
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_EVENTFD_H */
+
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index f589559cf07..4c03ee353e7 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -434,6 +434,10 @@ static inline struct block_device *bdget_disk(struct gendisk *disk, int index)
#endif
-#endif
+#else /* CONFIG_BLOCK */
+
+static inline void printk_all_partitions(void) { }
+
+#endif /* CONFIG_BLOCK */
#endif
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 37076b116ed..827ee748fd4 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -275,6 +275,7 @@ struct hid_item {
#define HID_QUIRK_LOGITECH_DESCRIPTOR 0x00100000
#define HID_QUIRK_DUPLICATE_USAGES 0x00200000
#define HID_QUIRK_RESET_LEDS 0x00400000
+#define HID_QUIRK_SWAPPED_MIN_MAX 0x00800000
/*
* This is the global environment of the parser. This information is
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 0e8da684ce6..aa83d416309 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -117,6 +117,7 @@
#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_I2CDEV 900
#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 45170b2fa25..276ccaa2670 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -65,9 +65,9 @@
.posix_timers = LIST_HEAD_INIT(sig.posix_timers), \
.cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \
.rlim = INIT_RLIMITS, \
- .pgrp = 1, \
+ .pgrp = 0, \
.tty_old_pgrp = NULL, \
- { .__session = 1}, \
+ { .__session = 0}, \
}
extern struct nsproxy init_nsproxy;
@@ -84,10 +84,33 @@ extern struct nsproxy init_nsproxy;
.count = ATOMIC_INIT(1), \
.action = { { { .sa_handler = NULL, } }, }, \
.siglock = __SPIN_LOCK_UNLOCKED(sighand.siglock), \
+ .signalfd_list = LIST_HEAD_INIT(sighand.signalfd_list), \
}
extern struct group_info init_groups;
+#define INIT_STRUCT_PID { \
+ .count = ATOMIC_INIT(1), \
+ .nr = 0, \
+ /* Don't put this struct pid in pid_hash */ \
+ .pid_chain = { .next = NULL, .pprev = NULL }, \
+ .tasks = { \
+ { .first = &init_task.pids[PIDTYPE_PID].node }, \
+ { .first = &init_task.pids[PIDTYPE_PGID].node }, \
+ { .first = &init_task.pids[PIDTYPE_SID].node }, \
+ }, \
+ .rcu = RCU_HEAD_INIT, \
+}
+
+#define INIT_PID_LINK(type) \
+{ \
+ .node = { \
+ .next = NULL, \
+ .pprev = &init_struct_pid.tasks[type].first, \
+ }, \
+ .pid = &init_struct_pid, \
+}
+
/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -139,6 +162,11 @@ extern struct group_info init_groups;
.cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \
.fs_excl = ATOMIC_INIT(0), \
.pi_lock = __SPIN_LOCK_UNLOCKED(tsk.pi_lock), \
+ .pids = { \
+ [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \
+ [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \
+ [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \
+ }, \
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
}
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index f7b01b9a35b..5323f627585 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -241,6 +241,16 @@ static inline void __deprecated save_and_cli(unsigned long *x)
#define save_and_cli(x) save_and_cli(&x)
#endif /* CONFIG_SMP */
+/* Some architectures might implement lazy enabling/disabling of
+ * interrupts. In some cases, such as stop_machine, we might want
+ * to ensure that after a local_irq_disable(), interrupts have
+ * really been disabled in hardware. Such architectures need to
+ * implement the following hook.
+ */
+#ifndef hard_irq_disable
+#define hard_irq_disable() do { } while(0)
+#endif
+
/* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
frequency threaded job scheduling. For almost all the purposes
tasklets are more than enough. F.e. all serial device BHs et
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 8645181fca0..45353d757cd 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -213,6 +213,17 @@ extern enum system_states {
extern void dump_stack(void);
+enum {
+ DUMP_PREFIX_NONE,
+ DUMP_PREFIX_ADDRESS,
+ DUMP_PREFIX_OFFSET
+};
+extern void hex_dump_to_buffer(const void *buf, size_t len, char *linebuf,
+ size_t linebuflen);
+extern void print_hex_dump(const char *level, int prefix_type,
+ void *buf, size_t len);
+#define hex_asc(x) "0123456789abcdef"[x]
+
#ifdef DEBUG
/* If you are writing a driver, please use dev_dbg instead */
#define pr_debug(fmt,arg...) \
@@ -299,8 +310,8 @@ static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char *
*
*/
#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
/*
* Check at compile time that something is of a particular type.
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 7906d750aa7..27d93627957 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -140,7 +140,6 @@ enum {
ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
ATA_DFLAG_NCQ_OFF = (1 << 9), /* device limited to non-NCQ mode */
- ATA_DFLAG_SUSPENDED = (1 << 10), /* device suspended */
ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
ATA_DFLAG_DETACH = (1 << 16),
@@ -191,6 +190,7 @@ enum {
ATA_PFLAG_LOADING = (1 << 4), /* boot/loading probe */
ATA_PFLAG_UNLOADING = (1 << 5), /* module is unloading */
ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */
+ ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */
ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
@@ -254,10 +254,6 @@ enum {
ATA_DMA_PAD_SZ = 4,
ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
- /* masks for port functions */
- ATA_PORT_PRIMARY = (1 << 0),
- ATA_PORT_SECONDARY = (1 << 1),
-
/* ering size */
ATA_ERING_SIZE = 32,
@@ -268,13 +264,9 @@ enum {
ATA_EH_REVALIDATE = (1 << 0),
ATA_EH_SOFTRESET = (1 << 1),
ATA_EH_HARDRESET = (1 << 2),
- ATA_EH_SUSPEND = (1 << 3),
- ATA_EH_RESUME = (1 << 4),
- ATA_EH_PM_FREEZE = (1 << 5),
ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
- ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_SUSPEND |
- ATA_EH_RESUME | ATA_EH_PM_FREEZE,
+ ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE,
/* ata_eh_info->flags */
ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */
@@ -466,7 +458,7 @@ struct ata_device {
struct ata_ering ering;
int spdn_cnt;
unsigned int horkage; /* List of broken features */
-#ifdef CONFIG_SATA_ACPI
+#ifdef CONFIG_ATA_ACPI
/* ACPI objects info */
acpi_handle obj_handle;
#endif
@@ -693,8 +685,8 @@ extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
extern void ata_port_disable(struct ata_port *);
extern void ata_std_ports(struct ata_ioports *ioaddr);
#ifdef CONFIG_PCI
-extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
- unsigned int n_ports);
+extern int ata_pci_init_one (struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi);
extern void ata_pci_remove_one (struct pci_dev *pdev);
#ifdef CONFIG_PM
extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg);
@@ -736,8 +728,6 @@ extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val);
extern int ata_port_online(struct ata_port *ap);
extern int ata_port_offline(struct ata_port *ap);
#ifdef CONFIG_PM
-extern int ata_scsi_device_resume(struct scsi_device *);
-extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
extern void ata_host_resume(struct ata_host *host);
#endif
@@ -861,11 +851,11 @@ struct pci_bits {
unsigned long val;
};
-extern int ata_pci_init_native_host(struct ata_host *host,
- unsigned int port_mask);
+extern int ata_pci_init_native_host(struct ata_host *host);
+extern int ata_pci_init_bmdma(struct ata_host *host);
extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
const struct ata_port_info * const * ppi,
- int n_ports, struct ata_host **r_host);
+ struct ata_host **r_host);
extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
#endif /* CONFIG_PCI */
@@ -1008,11 +998,6 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
return ata_class_absent(dev->class);
}
-static inline unsigned int ata_dev_ready(const struct ata_device *dev)
-{
- return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED);
-}
-
/*
* port helpers
*/
diff --git a/include/linux/list.h b/include/linux/list.h
index 9202703be2a..f29fc9c1a96 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -264,8 +264,8 @@ static inline void list_del_init(struct list_head *entry)
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
- __list_del(list->prev, list->next);
- list_add(list, head);
+ __list_del(list->prev, list->next);
+ list_add(list, head);
}
/**
@@ -276,8 +276,8 @@ static inline void list_move(struct list_head *list, struct list_head *head)
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
- __list_del(list->prev, list->next);
- list_add_tail(list, head);
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
}
/**
diff --git a/include/linux/magic.h b/include/linux/magic.h
index a9c6567fe70..9d713c03e3d 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -14,6 +14,7 @@
#define ISOFS_SUPER_MAGIC 0x9660
#define JFFS2_SUPER_MAGIC 0x72b6
#define KVMFS_SUPER_MAGIC 0x19700426
+#define ANON_INODE_FS_MAGIC 0x09041934
#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
diff --git a/include/linux/module.h b/include/linux/module.h
index 792d483c9af..e6e0f86ef5f 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -124,7 +124,7 @@ extern struct module __this_module;
*/
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
-/* Author, ideally of form NAME <EMAIL>[, NAME <EMAIL>]*[ and NAME <EMAIL>] */
+/* Author, ideally of form NAME[, NAME]*[ and NAME] */
#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
/* What your module does. */
diff --git a/include/linux/mpage.h b/include/linux/mpage.h
index cc5fb75af78..068a0c9946a 100644
--- a/include/linux/mpage.h
+++ b/include/linux/mpage.h
@@ -12,7 +12,6 @@
#ifdef CONFIG_BLOCK
struct writeback_control;
-typedef int (writepage_t)(struct page *page, struct writeback_control *wbc);
int mpage_readpages(struct address_space *mapping, struct list_head *pages,
unsigned nr_pages, get_block_t get_block);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 30446222b39..f671cd2f133 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -467,6 +467,8 @@ struct net_device
/* device index hash chain */
struct hlist_node index_hlist;
+ struct net_device *link_watch_next;
+
/* register/unregister state machine */
enum { NETREG_UNINITIALIZED=0,
NETREG_REGISTERED, /* completed register_netdevice */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 022edfa97ed..7e733a6ba4f 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -54,6 +54,14 @@ struct xt_entry_target
unsigned char data[0];
};
+#define XT_TARGET_INIT(__name, __size) \
+{ \
+ .target.u.user = { \
+ .target_size = XT_ALIGN(__size), \
+ .name = __name, \
+ }, \
+}
+
struct xt_standard_target
{
struct xt_entry_target target;
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index 24c8786d12e..584cd1b18f1 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -238,6 +238,47 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e
*/
#ifdef __KERNEL__
+/* Standard entry. */
+struct arpt_standard
+{
+ struct arpt_entry entry;
+ struct arpt_standard_target target;
+};
+
+struct arpt_error_target
+{
+ struct arpt_entry_target target;
+ char errorname[ARPT_FUNCTION_MAXNAMELEN];
+};
+
+struct arpt_error
+{
+ struct arpt_entry entry;
+ struct arpt_error_target target;
+};
+
+#define ARPT_ENTRY_INIT(__size) \
+{ \
+ .target_offset = sizeof(struct arpt_entry), \
+ .next_offset = (__size), \
+}
+
+#define ARPT_STANDARD_INIT(__verdict) \
+{ \
+ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_standard)), \
+ .target = XT_TARGET_INIT(ARPT_STANDARD_TARGET, \
+ sizeof(struct arpt_standard_target)), \
+ .target.verdict = -(__verdict) - 1, \
+}
+
+#define ARPT_ERROR_INIT \
+{ \
+ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_error)), \
+ .target = XT_TARGET_INIT(ARPT_ERROR_TARGET, \
+ sizeof(struct arpt_error_target)), \
+ .target.errorname = "ERROR", \
+}
+
#define arpt_register_target(tgt) \
({ (tgt)->family = NF_ARP; \
xt_register_target(tgt); })
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index 9527296595c..2f46dd728ee 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -295,6 +295,28 @@ struct ipt_error
struct ipt_error_target target;
};
+#define IPT_ENTRY_INIT(__size) \
+{ \
+ .target_offset = sizeof(struct ipt_entry), \
+ .next_offset = (__size), \
+}
+
+#define IPT_STANDARD_INIT(__verdict) \
+{ \
+ .entry = IPT_ENTRY_INIT(sizeof(struct ipt_standard)), \
+ .target = XT_TARGET_INIT(IPT_STANDARD_TARGET, \
+ sizeof(struct xt_standard_target)), \
+ .target.verdict = -(__verdict) - 1, \
+}
+
+#define IPT_ERROR_INIT \
+{ \
+ .entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \
+ .target = XT_TARGET_INIT(IPT_ERROR_TARGET, \
+ sizeof(struct ipt_error_target)), \
+ .target.errorname = "ERROR", \
+}
+
extern unsigned int ipt_do_table(struct sk_buff **pskb,
unsigned int hook,
const struct net_device *in,
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 61aa10412fc..4686f8342cb 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -123,6 +123,28 @@ struct ip6t_error
struct ip6t_error_target target;
};
+#define IP6T_ENTRY_INIT(__size) \
+{ \
+ .target_offset = sizeof(struct ip6t_entry), \
+ .next_offset = (__size), \
+}
+
+#define IP6T_STANDARD_INIT(__verdict) \
+{ \
+ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \
+ .target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \
+ sizeof(struct ip6t_standard_target)), \
+ .target.verdict = -(__verdict) - 1, \
+}
+
+#define IP6T_ERROR_INIT \
+{ \
+ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \
+ .target = XT_TARGET_INIT(IP6T_ERROR_TARGET, \
+ sizeof(struct ip6t_error_target)), \
+ .target.errorname = "ERROR", \
+}
+
/*
* New IP firewall options for [gs]etsockopt at the RAW IP level.
* Unlike BSD Linux inherits IP options so you don't have to use
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ae849f0d443..ccd85e4d3b8 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -370,6 +370,7 @@
#define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380
#define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c
+#define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390
#define PCI_VENDOR_ID_VLSI 0x1004
#define PCI_DEVICE_ID_VLSI_82C592 0x0005
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 2ac27f9997d..1e0e4e3423a 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -51,6 +51,8 @@ struct pid
struct rcu_head rcu;
};
+extern struct pid init_struct_pid;
+
struct pid_link
{
struct hlist_node node;
@@ -76,8 +78,7 @@ extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type);
* write-held.
*/
extern int FASTCALL(attach_pid(struct task_struct *task,
- enum pid_type type, int nr));
-
+ enum pid_type type, struct pid *pid));
extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type));
extern void FASTCALL(transfer_pid(struct task_struct *old,
struct task_struct *new, enum pid_type));
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 17b72d88c4c..a81897e2a24 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -88,6 +88,7 @@ struct sched_param {
struct exec_domain;
struct futex_pi_state;
+struct bio;
/*
* List of flags we want to share for kernel threads,
@@ -391,6 +392,7 @@ struct sighand_struct {
atomic_t count;
struct k_sigaction action[_NSIG];
spinlock_t siglock;
+ struct list_head signalfd_list;
};
struct pacct_struct {
@@ -469,6 +471,7 @@ struct signal_struct {
cputime_t utime, stime, cutime, cstime;
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
+ unsigned long inblock, oublock, cinblock, coublock;
/*
* Cumulative ns of scheduled CPU time for dead threads in the
@@ -1014,6 +1017,9 @@ struct task_struct {
/* journalling filesystem info */
void *journal_info;
+/* stacked block device info */
+ struct bio *bio_list, **bio_tail;
+
/* VM state */
struct reclaim_state *reclaim_state;
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 3fa0fab4a04..9a5eac508e5 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -233,6 +233,7 @@ static inline int valid_signal(unsigned long sig)
return sig <= _NSIG ? 1 : 0;
}
+extern int next_signal(struct sigpending *pending, sigset_t *mask);
extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern long do_sigpending(void __user *, unsigned long);
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h
new file mode 100644
index 00000000000..51042949569
--- /dev/null
+++ b/include/linux/signalfd.h
@@ -0,0 +1,97 @@
+/*
+ * include/linux/signalfd.h
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _LINUX_SIGNALFD_H
+#define _LINUX_SIGNALFD_H
+
+
+struct signalfd_siginfo {
+ __u32 signo;
+ __s32 err;
+ __s32 code;
+ __u32 pid;
+ __u32 uid;
+ __s32 fd;
+ __u32 tid;
+ __u32 band;
+ __u32 overrun;
+ __u32 trapno;
+ __s32 status;
+ __s32 svint;
+ __u64 svptr;
+ __u64 utime;
+ __u64 stime;
+ __u64 addr;
+
+ /*
+ * Pad strcture to 128 bytes. Remember to update the
+ * pad size when you add new memebers. We use a fixed
+ * size structure to avoid compatibility problems with
+ * future versions, and we leave extra space for additional
+ * members. We use fixed size members because this strcture
+ * comes out of a read(2) and we really don't want to have
+ * a compat on read(2).
+ */
+ __u8 __pad[48];
+};
+
+
+#ifdef __KERNEL__
+
+#ifdef CONFIG_SIGNALFD
+
+/*
+ * Deliver the signal to listening signalfd. This must be called
+ * with the sighand lock held. Same are the following that end up
+ * calling signalfd_deliver().
+ */
+void signalfd_deliver(struct task_struct *tsk, int sig);
+
+/*
+ * No need to fall inside signalfd_deliver() if no signal listeners
+ * are available.
+ */
+static inline void signalfd_notify(struct task_struct *tsk, int sig)
+{
+ if (unlikely(!list_empty(&tsk->sighand->signalfd_list)))
+ signalfd_deliver(tsk, sig);
+}
+
+/*
+ * The signal -1 is used to notify the signalfd that the sighand
+ * is on its way to be detached.
+ */
+static inline void signalfd_detach_locked(struct task_struct *tsk)
+{
+ if (unlikely(!list_empty(&tsk->sighand->signalfd_list)))
+ signalfd_deliver(tsk, -1);
+}
+
+static inline void signalfd_detach(struct task_struct *tsk)
+{
+ struct sighand_struct *sighand = tsk->sighand;
+
+ if (unlikely(!list_empty(&sighand->signalfd_list))) {
+ spin_lock_irq(&sighand->siglock);
+ signalfd_deliver(tsk, -1);
+ spin_unlock_irq(&sighand->siglock);
+ }
+}
+
+#else /* CONFIG_SIGNALFD */
+
+#define signalfd_deliver(t, s) do { } while (0)
+#define signalfd_notify(t, s) do { } while (0)
+#define signalfd_detach_locked(t) do { } while (0)
+#define signalfd_detach(t) do { } while (0)
+
+#endif /* CONFIG_SIGNALFD */
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_SIGNALFD_H */
+
diff --git a/include/linux/synclink.h b/include/linux/synclink.h
index c8b042667af..5562fbf7209 100644
--- a/include/linux/synclink.h
+++ b/include/linux/synclink.h
@@ -291,4 +291,28 @@ struct gpio_desc {
#define MGSL_IOCGGPIO _IOR(MGSL_MAGIC_IOC,17,struct gpio_desc)
#define MGSL_IOCWAITGPIO _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc)
+#ifdef __KERNEL__
+/* provide 32 bit ioctl compatibility on 64 bit systems */
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+struct MGSL_PARAMS32 {
+ compat_ulong_t mode;
+ unsigned char loopback;
+ unsigned short flags;
+ unsigned char encoding;
+ compat_ulong_t clock_speed;
+ unsigned char addr_filter;
+ unsigned short crc_type;
+ unsigned char preamble_length;
+ unsigned char preamble;
+ compat_ulong_t data_rate;
+ unsigned char data_bits;
+ unsigned char stop_bits;
+ unsigned char parity;
+};
+#define MGSL_IOCSPARAMS32 _IOW(MGSL_MAGIC_IOC,0,struct MGSL_PARAMS32)
+#define MGSL_IOCGPARAMS32 _IOR(MGSL_MAGIC_IOC,1,struct MGSL_PARAMS32)
+#endif
+#endif
+
#endif /* _SYNCLINK_H_ */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 3139f441229..b02070eac42 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -604,6 +604,10 @@ asmlinkage long sys_get_robust_list(int pid,
asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
size_t len);
asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
+asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask);
+asmlinkage long sys_timerfd(int ufd, int clockid, int flags,
+ const struct itimerspec __user *utmr);
+asmlinkage long sys_eventfd(unsigned int count);
int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
diff --git a/include/linux/task_io_accounting_ops.h b/include/linux/task_io_accounting_ops.h
index df2a319106b..1218733ec6b 100644
--- a/include/linux/task_io_accounting_ops.h
+++ b/include/linux/task_io_accounting_ops.h
@@ -10,11 +10,29 @@ static inline void task_io_account_read(size_t bytes)
current->ioac.read_bytes += bytes;
}
+/*
+ * We approximate number of blocks, because we account bytes only.
+ * A 'block' is 512 bytes
+ */
+static inline unsigned long task_io_get_inblock(const struct task_struct *p)
+{
+ return p->ioac.read_bytes >> 9;
+}
+
static inline void task_io_account_write(size_t bytes)
{
current->ioac.write_bytes += bytes;
}
+/*
+ * We approximate number of blocks, because we account bytes only.
+ * A 'block' is 512 bytes
+ */
+static inline unsigned long task_io_get_oublock(const struct task_struct *p)
+{
+ return p->ioac.write_bytes >> 9;
+}
+
static inline void task_io_account_cancelled_write(size_t bytes)
{
current->ioac.cancelled_write_bytes += bytes;
@@ -31,10 +49,20 @@ static inline void task_io_account_read(size_t bytes)
{
}
+static inline unsigned long task_io_get_inblock(const struct task_struct *p)
+{
+ return 0;
+}
+
static inline void task_io_account_write(size_t bytes)
{
}
+static inline unsigned long task_io_get_oublock(const struct task_struct *p)
+{
+ return 0;
+}
+
static inline void task_io_account_cancelled_write(size_t bytes)
{
}
diff --git a/include/linux/timerfd.h b/include/linux/timerfd.h
new file mode 100644
index 00000000000..cf2b10d7573
--- /dev/null
+++ b/include/linux/timerfd.h
@@ -0,0 +1,17 @@
+/*
+ * include/linux/timerfd.h
+ *
+ * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _LINUX_TIMERFD_H
+#define _LINUX_TIMERFD_H
+
+
+#define TFD_TIMER_ABSTIME (1 << 0)
+
+
+
+#endif /* _LINUX_TIMERFD_H */
+
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 659487e3ebe..85c95cd39bc 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -52,6 +52,11 @@
* This routine allows the tty driver to implement
* device-specific ioctl's. If the ioctl number passed in cmd
* is not recognized by the driver, it should return ENOIOCTLCMD.
+ *
+ * long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+ * unsigned int cmd, unsigned long arg);
+ *
+ * implement ioctl processing for 32 bit process on 64 bit system
*
* void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
*
@@ -132,6 +137,8 @@ struct tty_operations {
int (*chars_in_buffer)(struct tty_struct *tty);
int (*ioctl)(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+ long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg);
void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
void (*throttle)(struct tty_struct * tty);
void (*unthrottle)(struct tty_struct * tty);
@@ -193,6 +200,8 @@ struct tty_driver {
int (*chars_in_buffer)(struct tty_struct *tty);
int (*ioctl)(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+ long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg);
void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
void (*throttle)(struct tty_struct * tty);
void (*unthrottle)(struct tty_struct * tty);
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index d75932e2771..6226504d910 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -59,6 +59,11 @@
* low-level driver can "grab" an ioctl request before the line
* discpline has a chance to see it.
*
+ * long (*compat_ioctl)(struct tty_struct * tty, struct file * file,
+ * unsigned int cmd, unsigned long arg);
+ *
+ * Process ioctl calls from 32-bit process on 64-bit system
+ *
* void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
*
* This function notifies the line discpline that a change has
@@ -118,6 +123,8 @@ struct tty_ldisc {
const unsigned char * buf, size_t nr);
int (*ioctl)(struct tty_struct * tty, struct file * file,
unsigned int cmd, unsigned long arg);
+ long (*compat_ioctl)(struct tty_struct * tty, struct file * file,
+ unsigned int cmd, unsigned long arg);
void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
unsigned int (*poll)(struct tty_struct *, struct file *,
struct poll_table_struct *);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index daa6c125f66..050915b5957 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -111,9 +111,15 @@ balance_dirty_pages_ratelimited(struct address_space *mapping)
balance_dirty_pages_ratelimited_nr(mapping, 1);
}
+typedef int (*writepage_t)(struct page *page, struct writeback_control *wbc,
+ void *data);
+
int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
-extern int generic_writepages(struct address_space *mapping,
- struct writeback_control *wbc);
+int generic_writepages(struct address_space *mapping,
+ struct writeback_control *wbc);
+int write_cache_pages(struct address_space *mapping,
+ struct writeback_control *wbc, writepage_t writepage,
+ void *data);
int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
int sync_page_range(struct inode *inode, struct address_space *mapping,
loff_t pos, loff_t count);
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 796bcf151a3..d3f4f5a3821 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -58,6 +58,7 @@ struct saa7146_pgtable {
unsigned long offset;
/* used for custom pagetables (used for example by budget dvb cards) */
struct scatterlist *slist;
+ int nents;
};
struct saa7146_pci_extension_data {
@@ -157,6 +158,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt);
void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt);
int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length );
char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt);
+void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt);
void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data);
int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop);
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 50e33b0e934..cce20ed5cf6 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -216,6 +216,8 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data);
extern struct saa7146_use_ops saa7146_video_uops;
int saa7146_start_preview(struct saa7146_fh *fh);
int saa7146_stop_preview(struct saa7146_fh *fh);
+int saa7146_video_do_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg);
/* from saa7146_vbi.c */
extern struct saa7146_use_ops saa7146_vbi_uops;
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 1c6b8bd09b9..4732432f8eb 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -183,13 +183,6 @@ extern void nf_conntrack_hash_insert(struct nf_conn *ct);
extern void nf_conntrack_flush(void);
-extern struct nf_conntrack_helper *
-nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple);
-extern void nf_ct_helper_put(struct nf_conntrack_helper *helper);
-
-extern struct nf_conntrack_helper *
-__nf_conntrack_helper_find_byname(const char *name);
-
extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
const struct nf_conntrack_tuple *orig);
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index f32f714e5d9..96a58d8e1d3 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -56,9 +56,6 @@ struct nf_conntrack_l3proto
*/
int (*new)(struct nf_conn *conntrack, const struct sk_buff *skb);
- /* Called when a conntrack entry is destroyed */
- void (*destroy)(struct nf_conn *conntrack);
-
/*
* Called before tracking.
* *dataoff: offset of protocol header (TCP, UDP,...) in *pskb
diff --git a/include/net/netfilter/nf_nat_rule.h b/include/net/netfilter/nf_nat_rule.h
index e76565459ad..f9743187d57 100644
--- a/include/net/netfilter/nf_nat_rule.h
+++ b/include/net/netfilter/nf_nat_rule.h
@@ -10,16 +10,11 @@ extern int nf_nat_rule_find(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
- struct nf_conn *ct,
- struct nf_nat_info *info);
+ struct nf_conn *ct);
extern unsigned int
-alloc_null_binding(struct nf_conn *ct,
- struct nf_nat_info *info,
- unsigned int hooknum);
+alloc_null_binding(struct nf_conn *ct, unsigned int hooknum);
extern unsigned int
-alloc_null_binding_confirmed(struct nf_conn *ct,
- struct nf_nat_info *info,
- unsigned int hooknum);
+alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum);
#endif /* _NF_NAT_RULE_H */
diff --git a/include/net/udp.h b/include/net/udp.h
index 98755ebaf16..496f89d45c8 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -119,9 +119,16 @@ static inline void udp_lib_close(struct sock *sk, long timeout)
}
+struct udp_get_port_ops {
+ int (*saddr_cmp)(const struct sock *sk1, const struct sock *sk2);
+ int (*saddr_any)(const struct sock *sk);
+ unsigned int (*hash_port_and_rcv_saddr)(__u16 port,
+ const struct sock *sk);
+};
+
/* net/ipv4/udp.c */
extern int udp_get_port(struct sock *sk, unsigned short snum,
- int (*saddr_cmp)(const struct sock *, const struct sock *));
+ const struct udp_get_port_ops *ops);
extern void udp_err(struct sk_buff *, u32);
extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk,
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 635b0eafca9..50b4b424d1c 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -120,5 +120,5 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
extern void udplite4_register(void);
extern int udplite_get_port(struct sock *sk, unsigned short snum,
- int (*scmp)(const struct sock *, const struct sock *));
+ const struct udp_get_port_ops *ops);
#endif /* _UDPLITE_H */
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
index c149d3b2558..d647dae912b 100644
--- a/include/sound/ak4114.h
+++ b/include/sound/ak4114.h
@@ -73,7 +73,7 @@
/* AK4114_REQ_FORMAT bits */
#define AK4114_MONO (1<<7) /* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */
-#define AK4114_DIF2 (1<<5) /* Audio Data Control */
+#define AK4114_DIF2 (1<<6) /* Audio Data Control */
#define AK4114_DIF1 (1<<5) /* Audio Data Control */
#define AK4114_DIF0 (1<<4) /* Audio Data Control */
#define AK4114_DIF_16R (0) /* STDO: 16-bit, right justified */
@@ -158,7 +158,7 @@
#define AK4114_CHECK_NO_STAT (1<<0) /* no statistics */
#define AK4114_CHECK_NO_RATE (1<<1) /* no rate check */
-#define AK4114_CONTROLS 14
+#define AK4114_CONTROLS 15
typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data);
typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr);
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
index 8c88267e9be..d5c1396c4c9 100644
--- a/include/sound/mpu401.h
+++ b/include/sound/mpu401.h
@@ -50,6 +50,7 @@
#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */
+#define MPU401_INFO_UART_ONLY (1 << 5) /* No ENTER_UART cmd needed */
#define MPU401_MODE_BIT_INPUT 0
#define MPU401_MODE_BIT_OUTPUT 1
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index deff5a92efa..73334e0f823 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -603,11 +603,8 @@ do { \
read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \
} while (0)
-#define snd_pcm_group_for_each(pos, substream) \
- list_for_each(pos, &substream->group->substreams)
-
-#define snd_pcm_group_substream_entry(pos) \
- list_entry(pos, struct snd_pcm_substream, link_list)
+#define snd_pcm_group_for_each_entry(s, substream) \
+ list_for_each_entry(s, &substream->group->substreams, link_list)
static inline int snd_pcm_running(struct snd_pcm_substream *substream)
{
diff --git a/include/sound/version.h b/include/sound/version.h
index 42a18cc95f3..e820f0e7bdd 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
/* include/version.h. Generated by alsa/ksync script. */
-#define CONFIG_SND_VERSION "1.0.14rc3"
-#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)"
+#define CONFIG_SND_VERSION "1.0.14rc4"
+#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)"
diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h
new file mode 100644
index 00000000000..4eea63761a3
--- /dev/null
+++ b/include/video/atmel_lcdc.h
@@ -0,0 +1,196 @@
+/*
+ * Header file for AT91/AT32 LCD Controller
+ *
+ * Data structure and register user interface
+ *
+ * Copyright (C) 2007 Atmel 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.
+ *
+ * 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 __ATMEL_LCDC_H__
+#define __ATMEL_LCDC_H__
+
+ /* LCD Controller info data structure */
+struct atmel_lcdfb_info {
+ spinlock_t lock;
+ struct fb_info *info;
+ void __iomem *mmio;
+ unsigned long irq_base;
+
+ unsigned int guard_time;
+ struct platform_device *pdev;
+ struct clk *bus_clk;
+ struct clk *lcdc_clk;
+ unsigned int default_bpp;
+ unsigned int default_lcdcon2;
+ unsigned int default_dmacon;
+ void (*atmel_lcdfb_power_control)(int on);
+ struct fb_monspecs *default_monspecs;
+ u32 pseudo_palette[16];
+};
+
+#define ATMEL_LCDC_DMABADDR1 0x00
+#define ATMEL_LCDC_DMABADDR2 0x04
+#define ATMEL_LCDC_DMAFRMPT1 0x08
+#define ATMEL_LCDC_DMAFRMPT2 0x0c
+#define ATMEL_LCDC_DMAFRMADD1 0x10
+#define ATMEL_LCDC_DMAFRMADD2 0x14
+
+#define ATMEL_LCDC_DMAFRMCFG 0x18
+#define ATMEL_LCDC_FRSIZE (0x7fffff << 0)
+#define ATMEL_LCDC_BLENGTH_OFFSET 24
+#define ATMEL_LCDC_BLENGTH (0x7f << ATMEL_LCDC_BLENGTH_OFFSET)
+
+#define ATMEL_LCDC_DMACON 0x1c
+#define ATMEL_LCDC_DMAEN (0x1 << 0)
+#define ATMEL_LCDC_DMARST (0x1 << 1)
+#define ATMEL_LCDC_DMABUSY (0x1 << 2)
+#define ATMEL_LCDC_DMAUPDT (0x1 << 3)
+#define ATMEL_LCDC_DMA2DEN (0x1 << 4)
+
+#define ATMEL_LCDC_DMA2DCFG 0x20
+#define ATMEL_LCDC_ADDRINC_OFFSET 0
+#define ATMEL_LCDC_ADDRINC (0xffff)
+#define ATMEL_LCDC_PIXELOFF_OFFSET 24
+#define ATMEL_LCDC_PIXELOFF (0x1f << 24)
+
+#define ATMEL_LCDC_LCDCON1 0x0800
+#define ATMEL_LCDC_BYPASS (1 << 0)
+#define ATMEL_LCDC_CLKVAL_OFFSET 12
+#define ATMEL_LCDC_CLKVAL (0x1ff << ATMEL_LCDC_CLKVAL_OFFSET)
+#define ATMEL_LCDC_LINCNT (0x7ff << 21)
+
+#define ATMEL_LCDC_LCDCON2 0x0804
+#define ATMEL_LCDC_DISTYPE (3 << 0)
+#define ATMEL_LCDC_DISTYPE_STNMONO (0 << 0)
+#define ATMEL_LCDC_DISTYPE_STNCOLOR (1 << 0)
+#define ATMEL_LCDC_DISTYPE_TFT (2 << 0)
+#define ATMEL_LCDC_SCANMOD (1 << 2)
+#define ATMEL_LCDC_SCANMOD_SINGLE (0 << 2)
+#define ATMEL_LCDC_SCANMOD_DUAL (1 << 2)
+#define ATMEL_LCDC_IFWIDTH (3 << 3)
+#define ATMEL_LCDC_IFWIDTH_4 (0 << 3)
+#define ATMEL_LCDC_IFWIDTH_8 (1 << 3)
+#define ATMEL_LCDC_IFWIDTH_16 (2 << 3)
+#define ATMEL_LCDC_PIXELSIZE (7 << 5)
+#define ATMEL_LCDC_PIXELSIZE_1 (0 << 5)
+#define ATMEL_LCDC_PIXELSIZE_2 (1 << 5)
+#define ATMEL_LCDC_PIXELSIZE_4 (2 << 5)
+#define ATMEL_LCDC_PIXELSIZE_8 (3 << 5)
+#define ATMEL_LCDC_PIXELSIZE_16 (4 << 5)
+#define ATMEL_LCDC_PIXELSIZE_24 (5 << 5)
+#define ATMEL_LCDC_PIXELSIZE_32 (6 << 5)
+#define ATMEL_LCDC_INVVD (1 << 8)
+#define ATMEL_LCDC_INVVD_NORMAL (0 << 8)
+#define ATMEL_LCDC_INVVD_INVERTED (1 << 8)
+#define ATMEL_LCDC_INVFRAME (1 << 9 )
+#define ATMEL_LCDC_INVFRAME_NORMAL (0 << 9)
+#define ATMEL_LCDC_INVFRAME_INVERTED (1 << 9)
+#define ATMEL_LCDC_INVLINE (1 << 10)
+#define ATMEL_LCDC_INVLINE_NORMAL (0 << 10)
+#define ATMEL_LCDC_INVLINE_INVERTED (1 << 10)
+#define ATMEL_LCDC_INVCLK (1 << 11)
+#define ATMEL_LCDC_INVCLK_NORMAL (0 << 11)
+#define ATMEL_LCDC_INVCLK_INVERTED (1 << 11)
+#define ATMEL_LCDC_INVDVAL (1 << 12)
+#define ATMEL_LCDC_INVDVAL_NORMAL (0 << 12)
+#define ATMEL_LCDC_INVDVAL_INVERTED (1 << 12)
+#define ATMEL_LCDC_CLKMOD (1 << 15)
+#define ATMEL_LCDC_CLKMOD_ACTIVEDISPLAY (0 << 15)
+#define ATMEL_LCDC_CLKMOD_ALWAYSACTIVE (1 << 15)
+#define ATMEL_LCDC_MEMOR (1 << 31)
+#define ATMEL_LCDC_MEMOR_BIG (0 << 31)
+#define ATMEL_LCDC_MEMOR_LITTLE (1 << 31)
+
+#define ATMEL_LCDC_TIM1 0x0808
+#define ATMEL_LCDC_VFP (0xff << 0)
+#define ATMEL_LCDC_VBP_OFFSET 8
+#define ATMEL_LCDC_VBP (0xff << ATMEL_LCDC_VBP_OFFSET)
+#define ATMEL_LCDC_VPW_OFFSET 16
+#define ATMEL_LCDC_VPW (0x3f << ATMEL_LCDC_VPW_OFFSET)
+#define ATMEL_LCDC_VHDLY_OFFSET 24
+#define ATMEL_LCDC_VHDLY (0xf << ATMEL_LCDC_VHDLY_OFFSET)
+
+#define ATMEL_LCDC_TIM2 0x080c
+#define ATMEL_LCDC_HBP (0xff << 0)
+#define ATMEL_LCDC_HPW_OFFSET 8
+#define ATMEL_LCDC_HPW (0x3f << ATMEL_LCDC_HPW_OFFSET)
+#define ATMEL_LCDC_HFP_OFFSET 21
+#define ATMEL_LCDC_HFP (0x7ff << ATMEL_LCDC_HFP_OFFSET)
+
+#define ATMEL_LCDC_LCDFRMCFG 0x0810
+#define ATMEL_LCDC_LINEVAL (0x7ff << 0)
+#define ATMEL_LCDC_HOZVAL_OFFSET 21
+#define ATMEL_LCDC_HOZVAL (0x7ff << ATMEL_LCDC_HOZVAL_OFFSET)
+
+#define ATMEL_LCDC_FIFO 0x0814
+#define ATMEL_LCDC_FIFOTH (0xffff)
+
+#define ATMEL_LCDC_MVAL 0x0818
+
+#define ATMEL_LCDC_DP1_2 0x081c
+#define ATMEL_LCDC_DP4_7 0x0820
+#define ATMEL_LCDC_DP3_5 0x0824
+#define ATMEL_LCDC_DP2_3 0x0828
+#define ATMEL_LCDC_DP5_7 0x082c
+#define ATMEL_LCDC_DP3_4 0x0830
+#define ATMEL_LCDC_DP4_5 0x0834
+#define ATMEL_LCDC_DP6_7 0x0838
+#define ATMEL_LCDC_DP1_2_VAL (0xff)
+#define ATMEL_LCDC_DP4_7_VAL (0xfffffff)
+#define ATMEL_LCDC_DP3_5_VAL (0xfffff)
+#define ATMEL_LCDC_DP2_3_VAL (0xfff)
+#define ATMEL_LCDC_DP5_7_VAL (0xfffffff)
+#define ATMEL_LCDC_DP3_4_VAL (0xffff)
+#define ATMEL_LCDC_DP4_5_VAL (0xfffff)
+#define ATMEL_LCDC_DP6_7_VAL (0xfffffff)
+
+#define ATMEL_LCDC_PWRCON 0x083c
+#define ATMEL_LCDC_PWR (1 << 0)
+#define ATMEL_LCDC_GUARDT_OFFSET 1
+#define ATMEL_LCDC_GUARDT (0x7f << ATMEL_LCDC_GUARDT_OFFSET)
+#define ATMEL_LCDC_BUSY (1 << 31)
+
+#define ATMEL_LCDC_CONTRAST_CTR 0x0840
+#define ATMEL_LCDC_PS (3 << 0)
+#define ATMEL_LCDC_PS_DIV1 (0 << 0)
+#define ATMEL_LCDC_PS_DIV2 (1 << 0)
+#define ATMEL_LCDC_PS_DIV4 (2 << 0)
+#define ATMEL_LCDC_PS_DIV8 (3 << 0)
+#define ATMEL_LCDC_POL (1 << 2)
+#define ATMEL_LCDC_POL_NEGATIVE (0 << 2)
+#define ATMEL_LCDC_POL_POSITIVE (1 << 2)
+#define ATMEL_LCDC_ENA (1 << 3)
+#define ATMEL_LCDC_ENA_PWMDISABLE (0 << 3)
+#define ATMEL_LCDC_ENA_PWMENABLE (1 << 3)
+
+#define ATMEL_LCDC_CONTRAST_VAL 0x0844
+#define ATMEL_LCDC_CVAL (0xff)
+
+#define ATMEL_LCDC_IER 0x0848
+#define ATMEL_LCDC_IDR 0x084c
+#define ATMEL_LCDC_IMR 0x0850
+#define ATMEL_LCDC_ISR 0x0854
+#define ATMEL_LCDC_ICR 0x0858
+#define ATMEL_LCDC_LNI (1 << 0)
+#define ATMEL_LCDC_LSTLNI (1 << 1)
+#define ATMEL_LCDC_EOFI (1 << 2)
+#define ATMEL_LCDC_UFLWI (1 << 4)
+#define ATMEL_LCDC_OWRI (1 << 5)
+#define ATMEL_LCDC_MERI (1 << 6)
+
+#define ATMEL_LCDC_LUT(n) (0x0c00 + ((n)*4))
+
+#endif /* __ATMEL_LCDC_H__ */
diff --git a/include/video/pm3fb.h b/include/video/pm3fb.h
index 94c7d2da90e..d52e45a1e9b 100644
--- a/include/video/pm3fb.h
+++ b/include/video/pm3fb.h
@@ -7,9 +7,6 @@
* 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.
- *
- * $Header: /cvsroot/linux/drivers/video/pm3fb.h,v 1.1 2002/02/25 19:11:06 marcelo Exp $
- *
*/
#ifndef PM3FB_H
@@ -1119,117 +1116,10 @@
/* ***** pm3fb useful define and macro ***** */
/* ***************************************** */
-/* permedia3 -specific definitions */
-#define PM3_SCALE_TO_CLOCK(pr, fe, po) ((2 * PM3_REF_CLOCK * fe) / (pr * (1 << (po))))
-
-/* in case it's not in linux/pci.h */
-#ifndef PCI_DEVICE_ID_3DLABS_PERMEDIA3
-#define PCI_DEVICE_ID_3DLABS_PERMEDIA3 0x000a
-#endif
-
-/* max number of simultaneous board */
-#define PM3_MAX_BOARD 4
-
/* max size of options */
#define PM3_OPTIONS_SIZE 256
/* max size of font name */
#define PM3_FONTNAME_SIZE 40
-/* do we want accelerated console */
-#define PM3FB_USE_ACCEL 1
-
-/* for driver debugging ONLY */
-/* 0 = assert only, 1 = error, 2 = info, 3+ = verbose */
-/* define PM3FB_MASTER_DEBUG 1 */
-#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3)
-#define PM3FB_TRACE
-#endif /* defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 3) */
-
-#ifdef PM3FB_MASTER_DEBUG
-#define DPRINTK(l,a,b...) do { if ((l) <= PM3FB_MASTER_DEBUG) printk("pm3fb: %s: " a, __FUNCTION__ , ## b); } while (0)
-#define DASSERT(t,a,b...) do { if (!(t)) printk("pm3fb: _assert failed: %s: " a, __FUNCTION__ , ## b); } while (0)
-#ifdef PM3FB_TRACE
-#define DTRACE printk("pm3fb: _enter %s\n", __FUNCTION__)
-#else /* PM3FB_TRACE */
-#define DTRACE
-#endif /* PM3FB_TRACE */
-#else /* PM3FB_MASTER_DEBUG */
-#define DPRINTK(l,a,b...)
-#define DASSERT(t,a,b...)
-#define DTRACE
-#endif /* PM3FB_MASTER_DEBUG */
-
-#if defined(PM3FB_MASTER_DEBUG) && (PM3FB_MASTER_DEBUG >= 2)
-#define PM3_SHOW_CUR_MODE pm3fb_show_cur_mode(l_fb_info)
-#else
-#define PM3_SHOW_CUR_MODE /* pm3fb_show_cur_mode() */
-#endif
-
-/* ******************************************** */
-/* ***** A bunch of register-access macro ***** */
-/* ******************************************** */
-
-#define PM3_WRITE_REG(r, v) fb_writel(v, (l_fb_info->vIOBase + r))
-#define PM3_READ_REG(r) fb_readl((l_fb_info->vIOBase + r))
-
-
-#define depth2bpp(d) ((d + 7L) & ~7L)
-#define depth2ByPP(d) (depth2bpp(d) / 8)
-
-#define depth_supported(d) ((d == 8) || (d == 12) || (d == 15) || (d == 16) || (d==32))
-
-
-#define PM3_WAIT(n) \
-do{ \
- while(PM3_READ_REG(PM3InFIFOSpace)<(n)); \
-} while(0)
-
-#define PM3_DELAY(x) do { \
- int delay = x; \
- unsigned char tmp; \
- while(delay--){tmp = PM3_READ_REG(PM3InFIFOSpace);}; \
-} while(0)
-
-#define PM3_SLOW_WRITE_REG(r,v) \
-do{ \
- DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in slow write\n"); \
- mb(); \
- PM3_WAIT(1); \
- mb(); \
- PM3_WRITE_REG(r,v); \
-} while(0)
-
-#define PM3_SET_INDEX(index) \
-do{ \
- PM3_SLOW_WRITE_REG(PM3RD_IndexHigh,(((index)>>8)&0xff)); \
- PM3_SLOW_WRITE_REG(PM3RD_IndexLow,((index)&0xff)); \
-} while(0)
-
-#define PM3_WRITE_DAC_REG(r, v) \
-do { \
- DASSERT((l_fb_info->vIOBase != (unsigned char*)(-1)), "l_fb_info->vIOBase mapped in write dac reg\n"); \
- PM3_SET_INDEX(r); \
- mb(); \
- PM3_WRITE_REG(PM3RD_IndexedData, v); \
-} while (0)
-
-/* next one is really a function, added as a macro to be consistent */
-#define PM3_READ_DAC_REG(r) pm3fb_read_dac_reg(l_fb_info, r)
-
-
-#define PM3_COLOR(c) \
-do { \
- if (l_fb_info->current_par->depth == 8) \
- { \
- c = (c & 0xFF); \
- c = c | (c << 8); \
- } \
- if ((l_fb_info->current_par->depth == 8) || (depth2bpp(l_fb_info->current_par->depth) == 16)) \
- { \
- c = (c & 0xFFFF); \
- c = c | (c << 16); \
- } \
-} while (0)
-
#endif /* PM3FB_H */
diff --git a/init/Kconfig b/init/Kconfig
index 322b1f8c21b..4e009fde4b6 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -475,13 +475,53 @@ config FUTEX
support for "fast userspace mutexes". The resulting kernel may not
run glibc-based applications correctly.
+config ANON_INODES
+ bool "Enable anonymous inode source" if EMBEDDED
+ default y
+ help
+ Anonymous inode source for pseudo-files like epoll, signalfd,
+ timerfd and eventfd.
+
+ If unsure, say Y.
+
config EPOLL
bool "Enable eventpoll support" if EMBEDDED
default y
+ depends on ANON_INODES
help
Disabling this option will cause the kernel to be built without
support for epoll family of system calls.
+config SIGNALFD
+ bool "Enable signalfd() system call" if EMBEDDED
+ depends on ANON_INODES
+ default y
+ help
+ Enable the signalfd() system call that allows to receive signals
+ on a file descriptor.
+
+ If unsure, say Y.
+
+config TIMERFD
+ bool "Enable timerfd() system call" if EMBEDDED
+ depends on ANON_INODES
+ default y
+ help
+ Enable the timerfd() system call that allows to receive timer
+ events on a file descriptor.
+
+ If unsure, say Y.
+
+config EVENTFD
+ bool "Enable eventfd() system call" if EMBEDDED
+ depends on ANON_INODES
+ default y
+ help
+ Enable the eventfd() system call that allows to receive both
+ kernel notification (ie. KAIO) or userspace notifications.
+
+ If unsure, say Y.
+
config SHMEM
bool "Use full shmem filesystem" if EMBEDDED
default y
diff --git a/init/main.c b/init/main.c
index e8d080cab44..1940fa75e82 100644
--- a/init/main.c
+++ b/init/main.c
@@ -801,6 +801,7 @@ static int __init kernel_init(void * unused)
*/
init_pid_ns.child_reaper = current;
+ __set_special_pids(1, 1);
cad_pid = task_pid(current);
smp_prepare_cpus(max_cpus);
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index d17821d3f48..fab5707cb5f 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -681,6 +681,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
if (oflag & O_CREAT) {
if (dentry->d_inode) { /* entry already exists */
+ audit_inode(name, dentry->d_inode);
error = -EEXIST;
if (oflag & O_EXCL)
goto out;
@@ -693,6 +694,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
error = -ENOENT;
if (!dentry->d_inode)
goto out;
+ audit_inode(name, dentry->d_inode);
filp = do_open(dentry, oflag);
}
@@ -840,6 +842,7 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput;
info = MQUEUE_I(inode);
+ audit_inode(NULL, inode);
if (unlikely(!(filp->f_mode & FMODE_WRITE)))
goto out_fput;
@@ -923,6 +926,7 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput;
info = MQUEUE_I(inode);
+ audit_inode(NULL, inode);
if (unlikely(!(filp->f_mode & FMODE_READ)))
goto out_fput;
diff --git a/kernel/audit.h b/kernel/audit.h
index a3370232a39..815d6f5c04e 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -83,6 +83,7 @@ struct audit_krule {
u32 field_count;
char *filterkey; /* ties events to rules */
struct audit_field *fields;
+ struct audit_field *arch_f; /* quick access to arch field */
struct audit_field *inode_f; /* quick access to an inode field */
struct audit_watch *watch; /* associated watch */
struct list_head rlist; /* entry in audit_watch.rules list */
@@ -131,17 +132,19 @@ extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32,
extern int selinux_audit_rule_update(void);
#ifdef CONFIG_AUDITSYSCALL
-extern void __audit_signal_info(int sig, struct task_struct *t);
-static inline void audit_signal_info(int sig, struct task_struct *t)
+extern int __audit_signal_info(int sig, struct task_struct *t);
+static inline int audit_signal_info(int sig, struct task_struct *t)
{
- if (unlikely(audit_pid && t->tgid == audit_pid))
- __audit_signal_info(sig, t);
+ if (unlikely((audit_pid && t->tgid == audit_pid) ||
+ (audit_signals && !audit_dummy_context())))
+ return __audit_signal_info(sig, t);
+ return 0;
}
extern enum audit_state audit_filter_inodes(struct task_struct *,
struct audit_context *);
extern void audit_set_auditable(struct audit_context *);
#else
-#define audit_signal_info(s,t)
+#define audit_signal_info(s,t) AUDIT_DISABLED
#define audit_filter_inodes(t,c) AUDIT_DISABLED
#define audit_set_auditable(c)
#endif
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 3749193aed8..6c61263ff96 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -311,6 +311,43 @@ int audit_match_class(int class, unsigned syscall)
return classes[class][AUDIT_WORD(syscall)] & AUDIT_BIT(syscall);
}
+static inline int audit_match_class_bits(int class, u32 *mask)
+{
+ int i;
+
+ if (classes[class]) {
+ for (i = 0; i < AUDIT_BITMASK_SIZE; i++)
+ if (mask[i] & classes[class][i])
+ return 0;
+ }
+ return 1;
+}
+
+static int audit_match_signal(struct audit_entry *entry)
+{
+ struct audit_field *arch = entry->rule.arch_f;
+
+ if (!arch) {
+ /* When arch is unspecified, we must check both masks on biarch
+ * as syscall number alone is ambiguous. */
+ return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
+ entry->rule.mask) &&
+ audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
+ entry->rule.mask));
+ }
+
+ switch(audit_classify_arch(arch->val)) {
+ case 0: /* native */
+ return (audit_match_class_bits(AUDIT_CLASS_SIGNAL,
+ entry->rule.mask));
+ case 1: /* 32bit on biarch */
+ return (audit_match_class_bits(AUDIT_CLASS_SIGNAL_32,
+ entry->rule.mask));
+ default:
+ return 1;
+ }
+}
+
/* Common user-space to kernel rule translation. */
static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule)
{
@@ -429,6 +466,7 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
err = -EINVAL;
goto exit_free;
}
+ entry->rule.arch_f = f;
break;
case AUDIT_PERM:
if (f->val & ~15)
@@ -519,7 +557,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
case AUDIT_FSGID:
case AUDIT_LOGINUID:
case AUDIT_PERS:
- case AUDIT_ARCH:
case AUDIT_MSGTYPE:
case AUDIT_PPID:
case AUDIT_DEVMAJOR:
@@ -531,6 +568,9 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
case AUDIT_ARG2:
case AUDIT_ARG3:
break;
+ case AUDIT_ARCH:
+ entry->rule.arch_f = f;
+ break;
case AUDIT_SUBJ_USER:
case AUDIT_SUBJ_ROLE:
case AUDIT_SUBJ_TYPE:
@@ -1221,6 +1261,9 @@ static inline int audit_add_rule(struct audit_entry *entry,
#ifdef CONFIG_AUDITSYSCALL
if (!dont_count)
audit_n_rules++;
+
+ if (!audit_match_signal(entry))
+ audit_signals++;
#endif
mutex_unlock(&audit_filter_mutex);
@@ -1294,6 +1337,9 @@ static inline int audit_del_rule(struct audit_entry *entry,
#ifdef CONFIG_AUDITSYSCALL
if (!dont_count)
audit_n_rules--;
+
+ if (!audit_match_signal(entry))
+ audit_signals--;
#endif
mutex_unlock(&audit_filter_mutex);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 628c7ac590a..e36481ed61b 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -78,17 +78,15 @@ extern int audit_enabled;
* for saving names from getname(). */
#define AUDIT_NAMES 20
-/* AUDIT_NAMES_RESERVED is the number of slots we reserve in the
- * audit_context from being used for nameless inodes from
- * path_lookup. */
-#define AUDIT_NAMES_RESERVED 7
-
/* Indicates that audit should log the full pathname. */
#define AUDIT_NAME_FULL -1
/* number of audit rules */
int audit_n_rules;
+/* determines whether we collect data for signals sent */
+int audit_signals;
+
/* When fs/namei.c:getname() is called, we store the pointer in name and
* we don't let putname() free it (instead we free all of the saved
* pointers at syscall exit time).
@@ -114,6 +112,9 @@ struct audit_aux_data {
#define AUDIT_AUX_IPCPERM 0
+/* Number of target pids per aux struct. */
+#define AUDIT_AUX_PIDS 16
+
struct audit_aux_data_mq_open {
struct audit_aux_data d;
int oflag;
@@ -181,6 +182,13 @@ struct audit_aux_data_path {
struct vfsmount *mnt;
};
+struct audit_aux_data_pids {
+ struct audit_aux_data d;
+ pid_t target_pid[AUDIT_AUX_PIDS];
+ u32 target_sid[AUDIT_AUX_PIDS];
+ int pid_count;
+};
+
/* The per-task audit context. */
struct audit_context {
int dummy; /* must be the first element */
@@ -201,6 +209,7 @@ struct audit_context {
struct vfsmount * pwdmnt;
struct audit_context *previous; /* For nested syscalls */
struct audit_aux_data *aux;
+ struct audit_aux_data *aux_pids;
/* Save things to print about task_struct */
pid_t pid, ppid;
@@ -209,6 +218,9 @@ struct audit_context {
unsigned long personality;
int arch;
+ pid_t target_pid;
+ u32 target_sid;
+
#if AUDIT_DEBUG
int put_count;
int ino_count;
@@ -654,6 +666,10 @@ static inline void audit_free_aux(struct audit_context *context)
context->aux = aux->next;
kfree(aux);
}
+ while ((aux = context->aux_pids)) {
+ context->aux_pids = aux->next;
+ kfree(aux);
+ }
}
static inline void audit_zero_context(struct audit_context *context,
@@ -795,6 +811,29 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
audit_log_task_context(ab);
}
+static int audit_log_pid_context(struct audit_context *context, pid_t pid,
+ u32 sid)
+{
+ struct audit_buffer *ab;
+ char *s = NULL;
+ u32 len;
+ int rc = 0;
+
+ ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
+ if (!ab)
+ return 1;
+
+ if (selinux_sid_to_string(sid, &s, &len)) {
+ audit_log_format(ab, "opid=%d obj=(none)", pid);
+ rc = 1;
+ } else
+ audit_log_format(ab, "opid=%d obj=%s", pid, s);
+ audit_log_end(ab);
+ kfree(s);
+
+ return rc;
+}
+
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
{
int i, call_panic = 0;
@@ -973,6 +1012,21 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_end(ab);
}
+ for (aux = context->aux_pids; aux; aux = aux->next) {
+ struct audit_aux_data_pids *axs = (void *)aux;
+ int i;
+
+ for (i = 0; i < axs->pid_count; i++)
+ if (audit_log_pid_context(context, axs->target_pid[i],
+ axs->target_sid[i]))
+ call_panic = 1;
+ }
+
+ if (context->target_pid &&
+ audit_log_pid_context(context, context->target_pid,
+ context->target_sid))
+ call_panic = 1;
+
if (context->pwd && context->pwdmnt) {
ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
if (ab) {
@@ -1193,6 +1247,10 @@ void audit_syscall_exit(int valid, long return_code)
} else {
audit_free_names(context);
audit_free_aux(context);
+ context->aux = NULL;
+ context->aux_pids = NULL;
+ context->target_pid = 0;
+ context->target_sid = 0;
kfree(context->filterkey);
context->filterkey = NULL;
tsk->audit_context = context;
@@ -1226,6 +1284,7 @@ void __audit_getname(const char *name)
context->names[context->name_count].name_len = AUDIT_NAME_FULL;
context->names[context->name_count].name_put = 1;
context->names[context->name_count].ino = (unsigned long)-1;
+ context->names[context->name_count].osid = 0;
++context->name_count;
if (!context->pwd) {
read_lock(&current->fs->lock);
@@ -1279,6 +1338,28 @@ void audit_putname(const char *name)
#endif
}
+static int audit_inc_name_count(struct audit_context *context,
+ const struct inode *inode)
+{
+ if (context->name_count >= AUDIT_NAMES) {
+ if (inode)
+ printk(KERN_DEBUG "name_count maxed, losing inode data: "
+ "dev=%02x:%02x, inode=%lu",
+ MAJOR(inode->i_sb->s_dev),
+ MINOR(inode->i_sb->s_dev),
+ inode->i_ino);
+
+ else
+ printk(KERN_DEBUG "name_count maxed, losing inode data");
+ return 1;
+ }
+ context->name_count++;
+#if AUDIT_DEBUG
+ context->ino_count++;
+#endif
+ return 0;
+}
+
/* Copy inode data into an audit_names. */
static void audit_copy_inode(struct audit_names *name, const struct inode *inode)
{
@@ -1316,13 +1397,10 @@ void __audit_inode(const char *name, const struct inode *inode)
else {
/* FIXME: how much do we care about inodes that have no
* associated name? */
- if (context->name_count >= AUDIT_NAMES - AUDIT_NAMES_RESERVED)
+ if (audit_inc_name_count(context, inode))
return;
- idx = context->name_count++;
+ idx = context->name_count - 1;
context->names[idx].name = NULL;
-#if AUDIT_DEBUG
- ++context->ino_count;
-#endif
}
audit_copy_inode(&context->names[idx], inode);
}
@@ -1346,7 +1424,7 @@ void __audit_inode_child(const char *dname, const struct inode *inode,
{
int idx;
struct audit_context *context = current->audit_context;
- const char *found_name = NULL;
+ const char *found_parent = NULL, *found_child = NULL;
int dirlen = 0;
if (!context->in_syscall)
@@ -1354,88 +1432,73 @@ void __audit_inode_child(const char *dname, const struct inode *inode,
/* determine matching parent */
if (!dname)
- goto update_context;
- for (idx = 0; idx < context->name_count; idx++)
- if (context->names[idx].ino == parent->i_ino) {
- const char *name = context->names[idx].name;
+ goto add_names;
- if (!name)
- continue;
+ /* parent is more likely, look for it first */
+ for (idx = 0; idx < context->name_count; idx++) {
+ struct audit_names *n = &context->names[idx];
- if (audit_compare_dname_path(dname, name, &dirlen) == 0) {
- context->names[idx].name_len = dirlen;
- found_name = name;
- break;
- }
+ if (!n->name)
+ continue;
+
+ if (n->ino == parent->i_ino &&
+ !audit_compare_dname_path(dname, n->name, &dirlen)) {
+ n->name_len = dirlen; /* update parent data in place */
+ found_parent = n->name;
+ goto add_names;
}
+ }
-update_context:
- idx = context->name_count;
- if (context->name_count == AUDIT_NAMES) {
- printk(KERN_DEBUG "name_count maxed and losing %s\n",
- found_name ?: "(null)");
- return;
+ /* no matching parent, look for matching child */
+ for (idx = 0; idx < context->name_count; idx++) {
+ struct audit_names *n = &context->names[idx];
+
+ if (!n->name)
+ continue;
+
+ /* strcmp() is the more likely scenario */
+ if (!strcmp(dname, n->name) ||
+ !audit_compare_dname_path(dname, n->name, &dirlen)) {
+ if (inode)
+ audit_copy_inode(n, inode);
+ else
+ n->ino = (unsigned long)-1;
+ found_child = n->name;
+ goto add_names;
+ }
}
- context->name_count++;
-#if AUDIT_DEBUG
- context->ino_count++;
-#endif
- /* Re-use the name belonging to the slot for a matching parent directory.
- * All names for this context are relinquished in audit_free_names() */
- context->names[idx].name = found_name;
- context->names[idx].name_len = AUDIT_NAME_FULL;
- context->names[idx].name_put = 0; /* don't call __putname() */
-
- if (!inode)
- context->names[idx].ino = (unsigned long)-1;
- else
- audit_copy_inode(&context->names[idx], inode);
-
- /* A parent was not found in audit_names, so copy the inode data for the
- * provided parent. */
- if (!found_name) {
- idx = context->name_count;
- if (context->name_count == AUDIT_NAMES) {
- printk(KERN_DEBUG
- "name_count maxed and losing parent inode data: dev=%02x:%02x, inode=%lu",
- MAJOR(parent->i_sb->s_dev),
- MINOR(parent->i_sb->s_dev),
- parent->i_ino);
+
+add_names:
+ if (!found_parent) {
+ if (audit_inc_name_count(context, parent))
return;
- }
- context->name_count++;
-#if AUDIT_DEBUG
- context->ino_count++;
-#endif
+ idx = context->name_count - 1;
+ context->names[idx].name = NULL;
audit_copy_inode(&context->names[idx], parent);
}
-}
-/**
- * audit_inode_update - update inode info for last collected name
- * @inode: inode being audited
- *
- * When open() is called on an existing object with the O_CREAT flag, the inode
- * data audit initially collects is incorrect. This additional hook ensures
- * audit has the inode data for the actual object to be opened.
- */
-void __audit_inode_update(const struct inode *inode)
-{
- struct audit_context *context = current->audit_context;
- int idx;
+ if (!found_child) {
+ if (audit_inc_name_count(context, inode))
+ return;
+ idx = context->name_count - 1;
- if (!context->in_syscall || !inode)
- return;
+ /* Re-use the name belonging to the slot for a matching parent
+ * directory. All names for this context are relinquished in
+ * audit_free_names() */
+ if (found_parent) {
+ context->names[idx].name = found_parent;
+ context->names[idx].name_len = AUDIT_NAME_FULL;
+ /* don't call __putname() */
+ context->names[idx].name_put = 0;
+ } else {
+ context->names[idx].name = NULL;
+ }
- if (context->name_count == 0) {
- context->name_count++;
-#if AUDIT_DEBUG
- context->ino_count++;
-#endif
+ if (inode)
+ audit_copy_inode(&context->names[idx], inode);
+ else
+ context->names[idx].ino = (unsigned long)-1;
}
- idx = context->name_count - 1;
-
- audit_copy_inode(&context->names[idx], inode);
}
/**
@@ -1880,6 +1943,14 @@ int audit_sockaddr(int len, void *a)
return 0;
}
+void __audit_ptrace(struct task_struct *t)
+{
+ struct audit_context *context = current->audit_context;
+
+ context->target_pid = t->pid;
+ selinux_get_task_sid(t, &context->target_sid);
+}
+
/**
* audit_avc_path - record the granting or denial of permissions
* @dentry: dentry to record
@@ -1918,15 +1989,17 @@ int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
* If the audit subsystem is being terminated, record the task (pid)
* and uid that is doing that.
*/
-void __audit_signal_info(int sig, struct task_struct *t)
+int __audit_signal_info(int sig, struct task_struct *t)
{
+ struct audit_aux_data_pids *axp;
+ struct task_struct *tsk = current;
+ struct audit_context *ctx = tsk->audit_context;
extern pid_t audit_sig_pid;
extern uid_t audit_sig_uid;
extern u32 audit_sig_sid;
- if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
- struct task_struct *tsk = current;
- struct audit_context *ctx = tsk->audit_context;
+ if (audit_pid && t->tgid == audit_pid &&
+ (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1)) {
audit_sig_pid = tsk->pid;
if (ctx)
audit_sig_uid = ctx->loginuid;
@@ -1934,4 +2007,72 @@ void __audit_signal_info(int sig, struct task_struct *t)
audit_sig_uid = tsk->uid;
selinux_get_task_sid(tsk, &audit_sig_sid);
}
+
+ if (!audit_signals) /* audit_context checked in wrapper */
+ return 0;
+
+ /* optimize the common case by putting first signal recipient directly
+ * in audit_context */
+ if (!ctx->target_pid) {
+ ctx->target_pid = t->tgid;
+ selinux_get_task_sid(t, &ctx->target_sid);
+ return 0;
+ }
+
+ axp = (void *)ctx->aux_pids;
+ if (!axp || axp->pid_count == AUDIT_AUX_PIDS) {
+ axp = kzalloc(sizeof(*axp), GFP_ATOMIC);
+ if (!axp)
+ return -ENOMEM;
+
+ axp->d.type = AUDIT_OBJ_PID;
+ axp->d.next = ctx->aux_pids;
+ ctx->aux_pids = (void *)axp;
+ }
+ BUG_ON(axp->pid_count > AUDIT_AUX_PIDS);
+
+ axp->target_pid[axp->pid_count] = t->tgid;
+ selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
+ axp->pid_count++;
+
+ return 0;
+}
+
+/**
+ * audit_core_dumps - record information about processes that end abnormally
+ * @sig: signal value
+ *
+ * If a process ends with a core dump, something fishy is going on and we
+ * should record the event for investigation.
+ */
+void audit_core_dumps(long signr)
+{
+ struct audit_buffer *ab;
+ u32 sid;
+
+ if (!audit_enabled)
+ return;
+
+ if (signr == SIGQUIT) /* don't care for those */
+ return;
+
+ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
+ audit_log_format(ab, "auid=%u uid=%u gid=%u",
+ audit_get_loginuid(current->audit_context),
+ current->uid, current->gid);
+ selinux_get_task_sid(current, &sid);
+ if (sid) {
+ char *ctx = NULL;
+ u32 len;
+
+ if (selinux_sid_to_string(sid, &ctx, &len))
+ audit_log_format(ab, " ssid=%u", sid);
+ else
+ audit_log_format(ab, " subj=%s", ctx);
+ kfree(ctx);
+ }
+ audit_log_format(ab, " pid=%d comm=", current->pid);
+ audit_log_untrustedstring(ab, current->comm);
+ audit_log_format(ab, " sig=%ld", signr);
+ audit_log_end(ab);
}
diff --git a/kernel/compat.c b/kernel/compat.c
index cebb4c28c03..3bae3742c2a 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -475,8 +475,8 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
return min_length;
}
-static int get_compat_itimerspec(struct itimerspec *dst,
- struct compat_itimerspec __user *src)
+int get_compat_itimerspec(struct itimerspec *dst,
+ const struct compat_itimerspec __user *src)
{
if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
get_compat_timespec(&dst->it_value, &src->it_value))
@@ -484,8 +484,8 @@ static int get_compat_itimerspec(struct itimerspec *dst,
return 0;
}
-static int put_compat_itimerspec(struct compat_itimerspec __user *dst,
- struct itimerspec *src)
+int put_compat_itimerspec(struct compat_itimerspec __user *dst,
+ const struct itimerspec *src)
{
if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
put_compat_timespec(&src->it_value, &dst->it_value))
diff --git a/kernel/exit.c b/kernel/exit.c
index b0c6f0c3a2d..c6d14b8008d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -24,6 +24,7 @@
#include <linux/pid_namespace.h>
#include <linux/ptrace.h>
#include <linux/profile.h>
+#include <linux/signalfd.h>
#include <linux/mount.h>
#include <linux/proc_fs.h>
#include <linux/kthread.h>
@@ -42,6 +43,7 @@
#include <linux/audit.h> /* for audit_free() */
#include <linux/resource.h>
#include <linux/blkdev.h>
+#include <linux/task_io_accounting_ops.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -82,6 +84,14 @@ static void __exit_signal(struct task_struct *tsk)
sighand = rcu_dereference(tsk->sighand);
spin_lock(&sighand->siglock);
+ /*
+ * Notify that this sighand has been detached. This must
+ * be called with the tsk->sighand lock held. Also, this
+ * access tsk->sighand internally, so it must be called
+ * before tsk->sighand is reset.
+ */
+ signalfd_detach_locked(tsk);
+
posix_cpu_timers_exit(tsk);
if (atomic_dec_and_test(&sig->count))
posix_cpu_timers_exit_group(tsk);
@@ -113,6 +123,8 @@ static void __exit_signal(struct task_struct *tsk)
sig->nvcsw += tsk->nvcsw;
sig->nivcsw += tsk->nivcsw;
sig->sched_time += tsk->sched_time;
+ sig->inblock += task_io_get_inblock(tsk);
+ sig->oublock += task_io_get_oublock(tsk);
sig = NULL; /* Marker for below. */
}
@@ -299,12 +311,12 @@ void __set_special_pids(pid_t session, pid_t pgrp)
if (process_session(curr) != session) {
detach_pid(curr, PIDTYPE_SID);
set_signal_session(curr->signal, session);
- attach_pid(curr, PIDTYPE_SID, session);
+ attach_pid(curr, PIDTYPE_SID, find_pid(session));
}
if (process_group(curr) != pgrp) {
detach_pid(curr, PIDTYPE_PGID);
curr->signal->pgrp = pgrp;
- attach_pid(curr, PIDTYPE_PGID, pgrp);
+ attach_pid(curr, PIDTYPE_PGID, find_pid(pgrp));
}
}
@@ -1193,6 +1205,12 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
p->nvcsw + sig->nvcsw + sig->cnvcsw;
psig->cnivcsw +=
p->nivcsw + sig->nivcsw + sig->cnivcsw;
+ psig->cinblock +=
+ task_io_get_inblock(p) +
+ sig->inblock + sig->cinblock;
+ psig->coublock +=
+ task_io_get_oublock(p) +
+ sig->oublock + sig->coublock;
spin_unlock_irq(&p->parent->sighand->siglock);
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 5dd3979747f..49530e40ea8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -875,6 +875,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
+ sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
sig->sched_time = 0;
INIT_LIST_HEAD(&sig->cpu_timers[0]);
INIT_LIST_HEAD(&sig->cpu_timers[1]);
@@ -955,7 +956,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr,
- int pid)
+ struct pid *pid)
{
int retval;
struct task_struct *p = NULL;
@@ -1022,7 +1023,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->did_exec = 0;
delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
copy_flags(clone_flags, p);
- p->pid = pid;
+ p->pid = pid_nr(pid);
retval = -EFAULT;
if (clone_flags & CLONE_PARENT_SETTID)
if (put_user(p->pid, parent_tidptr))
@@ -1251,13 +1252,13 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->signal->tty = current->signal->tty;
p->signal->pgrp = process_group(current);
set_signal_session(p->signal, process_session(current));
- attach_pid(p, PIDTYPE_PGID, process_group(p));
- attach_pid(p, PIDTYPE_SID, process_session(p));
+ attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
+ attach_pid(p, PIDTYPE_SID, task_session(current));
list_add_tail_rcu(&p->tasks, &init_task.tasks);
__get_cpu_var(process_counts)++;
}
- attach_pid(p, PIDTYPE_PID, p->pid);
+ attach_pid(p, PIDTYPE_PID, pid);
nr_threads++;
}
@@ -1321,7 +1322,8 @@ struct task_struct * __cpuinit fork_idle(int cpu)
struct task_struct *task;
struct pt_regs regs;
- task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL, 0);
+ task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL,
+ &init_struct_pid);
if (!IS_ERR(task))
init_idle(task, cpu);
@@ -1371,7 +1373,7 @@ long do_fork(unsigned long clone_flags,
clone_flags |= CLONE_PTRACE;
}
- p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, nr);
+ p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid);
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid after that point, if the thread exits quickly.
@@ -1420,12 +1422,15 @@ long do_fork(unsigned long clone_flags,
#define ARCH_MIN_MMSTRUCT_ALIGN 0
#endif
-static void sighand_ctor(void *data, struct kmem_cache *cachep, unsigned long flags)
+static void sighand_ctor(void *data, struct kmem_cache *cachep,
+ unsigned long flags)
{
struct sighand_struct *sighand = data;
- if (flags & SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
spin_lock_init(&sighand->siglock);
+ INIT_LIST_HEAD(&sighand->signalfd_list);
+ }
}
void __init proc_caches_init(void)
@@ -1451,7 +1456,6 @@ void __init proc_caches_init(void)
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
}
-
/*
* Check constraints on flags passed to the unshare system call and
* force unsharing of additional process context as appropriate.
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index ddde0ef9ccd..b4f1674fca7 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -27,6 +27,10 @@ static int irq_affinity_read_proc(char *page, char **start, off_t off,
return len;
}
+#ifndef is_affinity_mask_valid
+#define is_affinity_mask_valid(val) 1
+#endif
+
int no_irq_affinity;
static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
unsigned long count, void *data)
@@ -42,6 +46,9 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
if (err)
return err;
+ if (!is_affinity_mask_valid(new_value))
+ return -EINVAL;
+
/*
* Do not allow disabling IRQs completely - it's a too easy
* way to make the system unusable accidentally :-) At least
diff --git a/kernel/pid.c b/kernel/pid.c
index d3ad724afa8..eb66bd2953a 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -27,11 +27,13 @@
#include <linux/bootmem.h>
#include <linux/hash.h>
#include <linux/pid_namespace.h>
+#include <linux/init_task.h>
#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
static struct hlist_head *pid_hash;
static int pidhash_shift;
static struct kmem_cache *pid_cachep;
+struct pid init_struct_pid = INIT_STRUCT_PID;
int pid_max = PID_MAX_DEFAULT;
@@ -247,13 +249,16 @@ struct pid * fastcall find_pid(int nr)
}
EXPORT_SYMBOL_GPL(find_pid);
-int fastcall attach_pid(struct task_struct *task, enum pid_type type, int nr)
+/*
+ * attach_pid() must be called with the tasklist_lock write-held.
+ */
+int fastcall attach_pid(struct task_struct *task, enum pid_type type,
+ struct pid *pid)
{
struct pid_link *link;
- struct pid *pid;
link = &task->pids[type];
- link->pid = pid = find_pid(nr);
+ link->pid = pid;
hlist_add_head_rcu(&link->node, &pid->tasks[type]);
return 0;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 4d50e06fd74..ad7949a589d 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -18,6 +18,7 @@
#include <linux/ptrace.h>
#include <linux/security.h>
#include <linux/signal.h>
+#include <linux/audit.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task)
{
int retval;
+ audit_ptrace(task);
+
retval = -EPERM;
if (task->pid <= 1)
goto out;
diff --git a/kernel/signal.c b/kernel/signal.c
index 2ac3a668d9d..364fc95bf97 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -21,6 +21,7 @@
#include <linux/syscalls.h>
#include <linux/ptrace.h>
#include <linux/signal.h>
+#include <linux/signalfd.h>
#include <linux/capability.h>
#include <linux/freezer.h>
#include <linux/pid_namespace.h>
@@ -113,8 +114,7 @@ void recalc_sigpending(void)
/* Given the mask, find the first available signal that should be serviced. */
-static int
-next_signal(struct sigpending *pending, sigset_t *mask)
+int next_signal(struct sigpending *pending, sigset_t *mask)
{
unsigned long i, *s, *m, x;
int sig = 0;
@@ -497,6 +497,11 @@ static int check_kill_permission(int sig, struct siginfo *info,
int error = -EINVAL;
if (!valid_signal(sig))
return error;
+
+ error = audit_signal_info(sig, t); /* Let audit system see the signal */
+ if (error)
+ return error;
+
error = -EPERM;
if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
&& ((sig != SIGCONT) ||
@@ -506,10 +511,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
&& !capable(CAP_KILL))
return error;
- error = security_task_kill(t, info, sig, 0);
- if (!error)
- audit_signal_info(sig, t); /* Let audit system see the signal */
- return error;
+ return security_task_kill(t, info, sig, 0);
}
/* forward decl */
@@ -630,6 +632,12 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
int ret = 0;
/*
+ * Deliver the signal to listening signalfds. This must be called
+ * with the sighand lock held.
+ */
+ signalfd_notify(t, sig);
+
+ /*
* fast-pathed signals for kernel-internal things like SIGSTOP
* or SIGKILL.
*/
@@ -1280,6 +1288,11 @@ int send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
ret = 1;
goto out;
}
+ /*
+ * Deliver the signal to listening signalfds. This must be called
+ * with the sighand lock held.
+ */
+ signalfd_notify(p, sig);
list_add_tail(&q->list, &p->pending.list);
sigaddset(&p->pending.signal, sig);
@@ -1323,6 +1336,11 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
q->info.si_overrun++;
goto out;
}
+ /*
+ * Deliver the signal to listening signalfds. This must be called
+ * with the sighand lock held.
+ */
+ signalfd_notify(p, sig);
/*
* Put this signal on the shared-pending queue.
@@ -1983,6 +2001,8 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
/*
* If you change siginfo_t structure, please be sure
* this code is fixed accordingly.
+ * Please remember to update the signalfd_copyinfo() function
+ * inside fs/signalfd.c too, in case siginfo_t changes.
* It should never copy any pad contained in the structure
* to avoid security leaks, but must copy the generic
* 3 ints plus the relevant union member.
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index daabb74ee0b..fcee2a8e6da 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -8,6 +8,8 @@
#include <linux/sched.h>
#include <linux/stop_machine.h>
#include <linux/syscalls.h>
+#include <linux/interrupt.h>
+
#include <asm/atomic.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
@@ -45,6 +47,7 @@ static int stopmachine(void *cpu)
if (stopmachine_state == STOPMACHINE_DISABLE_IRQ
&& !irqs_disabled) {
local_irq_disable();
+ hard_irq_disable();
irqs_disabled = 1;
/* Ack: irqs disabled. */
smp_mb(); /* Must read state first. */
@@ -124,6 +127,7 @@ static int stop_machine(void)
/* Make them disable irqs. */
local_irq_disable();
+ hard_irq_disable();
stopmachine_set_state(STOPMACHINE_DISABLE_IRQ);
return 0;
diff --git a/kernel/sys.c b/kernel/sys.c
index cdb7e9457ba..872271ccc38 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -14,6 +14,7 @@
#include <linux/prctl.h>
#include <linux/highuid.h>
#include <linux/fs.h>
+#include <linux/resource.h>
#include <linux/kernel.h>
#include <linux/kexec.h>
#include <linux/workqueue.h>
@@ -29,6 +30,7 @@
#include <linux/signal.h>
#include <linux/cn_proc.h>
#include <linux/getcpu.h>
+#include <linux/task_io_accounting_ops.h>
#include <linux/compat.h>
#include <linux/syscalls.h>
@@ -658,7 +660,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
int error = -EINVAL;
struct pid *pgrp;
- if (which > 2 || which < 0)
+ if (which > PRIO_USER || which < PRIO_PROCESS)
goto out;
/* normalize: avoid signed division (rounding problems) */
@@ -722,7 +724,7 @@ asmlinkage long sys_getpriority(int which, int who)
long niceval, retval = -ESRCH;
struct pid *pgrp;
- if (which > 2 || which < 0)
+ if (which > PRIO_USER || which < PRIO_PROCESS)
return -EINVAL;
read_lock(&tasklist_lock);
@@ -1486,7 +1488,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
if (process_group(p) != pgid) {
detach_pid(p, PIDTYPE_PGID);
p->signal->pgrp = pgid;
- attach_pid(p, PIDTYPE_PGID, pgid);
+ attach_pid(p, PIDTYPE_PGID, find_pid(pgid));
}
err = 0;
@@ -2082,6 +2084,8 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
r->ru_nivcsw = p->signal->cnivcsw;
r->ru_minflt = p->signal->cmin_flt;
r->ru_majflt = p->signal->cmaj_flt;
+ r->ru_inblock = p->signal->cinblock;
+ r->ru_oublock = p->signal->coublock;
if (who == RUSAGE_CHILDREN)
break;
@@ -2093,6 +2097,8 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
r->ru_nivcsw += p->signal->nivcsw;
r->ru_minflt += p->signal->min_flt;
r->ru_majflt += p->signal->maj_flt;
+ r->ru_inblock += p->signal->inblock;
+ r->ru_oublock += p->signal->oublock;
t = p;
do {
utime = cputime_add(utime, t->utime);
@@ -2101,6 +2107,8 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
r->ru_nivcsw += t->nivcsw;
r->ru_minflt += t->min_flt;
r->ru_majflt += t->maj_flt;
+ r->ru_inblock += task_io_get_inblock(t);
+ r->ru_oublock += task_io_get_oublock(t);
t = next_thread(t);
} while (t != p);
break;
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index d7306d0f3df..7e11e2c98bf 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -141,3 +141,10 @@ cond_syscall(compat_sys_migrate_pages);
cond_syscall(sys_bdflush);
cond_syscall(sys_ioprio_set);
cond_syscall(sys_ioprio_get);
+
+/* New file descriptors */
+cond_syscall(sys_signalfd);
+cond_syscall(sys_timerfd);
+cond_syscall(compat_sys_signalfd);
+cond_syscall(compat_sys_timerfd);
+cond_syscall(sys_eventfd);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index ee05b8a061b..fbc5c622acb 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -438,6 +438,7 @@ config FAULT_INJECTION_DEBUG_FS
config FAULT_INJECTION_STACKTRACE_FILTER
bool "stacktrace filter for fault-injection capabilities"
depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
+ depends on !X86_64
select STACKTRACE
select FRAME_POINTER
help
diff --git a/lib/Makefile b/lib/Makefile
index 1f65b4613e0..c8c8e20784c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -13,7 +13,7 @@ lib-$(CONFIG_SMP) += cpumask.o
lib-y += kobject.o kref.o kobject_uevent.o klist.o
obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
- bust_spinlocks.o
+ bust_spinlocks.o hexdump.o
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/audit.c b/lib/audit.c
index 3b1289fadf0..8e7dc1c63aa 100644
--- a/lib/audit.c
+++ b/lib/audit.c
@@ -23,6 +23,16 @@ static unsigned chattr_class[] = {
~0U
};
+static unsigned signal_class[] = {
+#include <asm-generic/audit_signal.h>
+~0U
+};
+
+int audit_classify_arch(int arch)
+{
+ return 0;
+}
+
int audit_classify_syscall(int abi, unsigned syscall)
{
switch(syscall) {
@@ -49,6 +59,7 @@ static int __init audit_classes_init(void)
audit_register_class(AUDIT_CLASS_READ, read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);
audit_register_class(AUDIT_CLASS_CHATTR, chattr_class);
+ audit_register_class(AUDIT_CLASS_SIGNAL, signal_class);
return 0;
}
diff --git a/lib/hexdump.c b/lib/hexdump.c
new file mode 100644
index 00000000000..e6da5b7fc29
--- /dev/null
+++ b/lib/hexdump.c
@@ -0,0 +1,104 @@
+/*
+ * lib/hexdump.c
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+/**
+ * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
+ * @buf: data blob to dump
+ * @len: number of bytes in the @buf
+ * @linebuf: where to put the converted data
+ * @linebuflen: total size of @linebuf, including space for terminating NUL
+ *
+ * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
+ * 16 bytes of input data converted to hex + ASCII output.
+ *
+ * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
+ * to a hex + ASCII dump at the supplied memory location.
+ * The converted output is always NUL-terminated.
+ *
+ * E.g.:
+ * hex_dump_to_buffer(frame->data, frame->len, linebuf, sizeof(linebuf));
+ *
+ * example output buffer:
+ * 40414243 44454647 48494a4b 4c4d4e4f @ABCDEFGHIJKLMNO
+ */
+void hex_dump_to_buffer(const void *buf, size_t len, char *linebuf,
+ size_t linebuflen)
+{
+ const u8 *ptr = buf;
+ u8 ch;
+ int j, lx = 0;
+
+ for (j = 0; (j < 16) && (j < len) && (lx + 3) < linebuflen; j++) {
+ if (j && !(j % 4))
+ linebuf[lx++] = ' ';
+ ch = ptr[j];
+ linebuf[lx++] = hex_asc(ch >> 4);
+ linebuf[lx++] = hex_asc(ch & 0x0f);
+ }
+ if ((lx + 2) < linebuflen) {
+ linebuf[lx++] = ' ';
+ linebuf[lx++] = ' ';
+ }
+ for (j = 0; (j < 16) && (j < len) && (lx + 2) < linebuflen; j++)
+ linebuf[lx++] = isprint(ptr[j]) ? ptr[j] : '.';
+ linebuf[lx++] = '\0';
+}
+EXPORT_SYMBOL(hex_dump_to_buffer);
+
+/**
+ * print_hex_dump - print a text hex dump to syslog for a binary blob of data
+ * @level: kernel log level (e.g. KERN_DEBUG)
+ * @prefix_type: controls whether prefix of an offset, address, or none
+ * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
+ * @buf: data blob to dump
+ * @len: number of bytes in the @buf
+ *
+ * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump
+ * to the kernel log at the specified kernel log level, with an optional
+ * leading prefix.
+ *
+ * E.g.:
+ * print_hex_dump(KERN_DEBUG, DUMP_PREFIX_ADDRESS, frame->data, frame->len);
+ *
+ * Example output using %DUMP_PREFIX_OFFSET:
+ * 0009ab42: 40414243 44454647 48494a4b 4c4d4e4f @ABCDEFGHIJKLMNO
+ * Example output using %DUMP_PREFIX_ADDRESS:
+ * ffffffff88089af0: 70717273 74757677 78797a7b 7c7d7e7f pqrstuvwxyz{|}~.
+ */
+void print_hex_dump(const char *level, int prefix_type, void *buf, size_t len)
+{
+ u8 *ptr = buf;
+ int i, linelen, remaining = len;
+ unsigned char linebuf[100];
+
+ for (i = 0; i < len; i += 16) {
+ linelen = min(remaining, 16);
+ remaining -= 16;
+ hex_dump_to_buffer(ptr + i, linelen, linebuf, sizeof(linebuf));
+
+ switch (prefix_type) {
+ case DUMP_PREFIX_ADDRESS:
+ printk("%s%*p: %s\n", level,
+ (int)(2 * sizeof(void *)), ptr + i, linebuf);
+ break;
+ case DUMP_PREFIX_OFFSET:
+ printk("%s%.8x: %s\n", level, i, linebuf);
+ break;
+ default:
+ printk("%s%s\n", level, linebuf);
+ break;
+ }
+ }
+}
+EXPORT_SYMBOL(print_hex_dump);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 63cd88840eb..eec1481ba44 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -588,31 +588,27 @@ void __init page_writeback_init(void)
}
/**
- * generic_writepages - walk the list of dirty pages of the given address space and writepage() all of them.
+ * write_cache_pages - walk the list of dirty pages of the given address space and write all of them.
* @mapping: address space structure to write
* @wbc: subtract the number of written pages from *@wbc->nr_to_write
+ * @writepage: function called for each page
+ * @data: data passed to writepage function
*
- * This is a library function, which implements the writepages()
- * address_space_operation.
- *
- * If a page is already under I/O, generic_writepages() skips it, even
+ * If a page is already under I/O, write_cache_pages() skips it, even
* if it's dirty. This is desirable behaviour for memory-cleaning writeback,
* but it is INCORRECT for data-integrity system calls such as fsync(). fsync()
* and msync() need to guarantee that all the data which was dirty at the time
* the call was made get new I/O started against them. If wbc->sync_mode is
* WB_SYNC_ALL then we were called for data integrity and we must wait for
* existing IO to complete.
- *
- * Derived from mpage_writepages() - if you fix this you should check that
- * also!
*/
-int generic_writepages(struct address_space *mapping,
- struct writeback_control *wbc)
+int write_cache_pages(struct address_space *mapping,
+ struct writeback_control *wbc, writepage_t writepage,
+ void *data)
{
struct backing_dev_info *bdi = mapping->backing_dev_info;
int ret = 0;
int done = 0;
- int (*writepage)(struct page *page, struct writeback_control *wbc);
struct pagevec pvec;
int nr_pages;
pgoff_t index;
@@ -625,12 +621,6 @@ int generic_writepages(struct address_space *mapping,
return 0;
}
- writepage = mapping->a_ops->writepage;
-
- /* deal with chardevs and other special file */
- if (!writepage)
- return 0;
-
pagevec_init(&pvec, 0);
if (wbc->range_cyclic) {
index = mapping->writeback_index; /* Start from prev offset */
@@ -682,8 +672,7 @@ retry:
continue;
}
- ret = (*writepage)(page, wbc);
- mapping_set_error(mapping, ret);
+ ret = (*writepage)(page, wbc, data);
if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
unlock_page(page);
@@ -710,6 +699,38 @@ retry:
mapping->writeback_index = index;
return ret;
}
+EXPORT_SYMBOL(write_cache_pages);
+
+/*
+ * Function used by generic_writepages to call the real writepage
+ * function and set the mapping flags on error
+ */
+static int __writepage(struct page *page, struct writeback_control *wbc,
+ void *data)
+{
+ struct address_space *mapping = data;
+ int ret = mapping->a_ops->writepage(page, wbc);
+ mapping_set_error(mapping, ret);
+ return ret;
+}
+
+/**
+ * generic_writepages - walk the list of dirty pages of the given address space and writepage() all of them.
+ * @mapping: address space structure to write
+ * @wbc: subtract the number of written pages from *@wbc->nr_to_write
+ *
+ * This is a library function, which implements the writepages()
+ * address_space_operation.
+ */
+int generic_writepages(struct address_space *mapping,
+ struct writeback_control *wbc)
+{
+ /* deal with chardevs and other special file */
+ if (!mapping->a_ops->writepage)
+ return 0;
+
+ return write_cache_pages(mapping, wbc, __writepage, mapping);
+}
EXPORT_SYMBOL(generic_writepages);
diff --git a/mm/thrash.c b/mm/thrash.c
index 9ef9071f99b..c4c5205a9c3 100644
--- a/mm/thrash.c
+++ b/mm/thrash.c
@@ -48,9 +48,8 @@ void grab_swap_token(void)
if (current_interval < current->mm->last_interval)
current->mm->token_priority++;
else {
- current->mm->token_priority--;
- if (unlikely(current->mm->token_priority < 0))
- current->mm->token_priority = 0;
+ if (likely(current->mm->token_priority > 0))
+ current->mm->token_priority--;
}
/* Check if we deserve the token */
if (current->mm->token_priority >
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 9832d9a41d8..8faf27e5aa9 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -698,7 +698,7 @@ static void __devinit start_cpu_timer(int cpu)
{
struct delayed_work *vmstat_work = &per_cpu(vmstat_work, cpu);
- INIT_DELAYED_WORK(vmstat_work, vmstat_update);
+ INIT_DELAYED_WORK_DEFERRABLE(vmstat_work, vmstat_update);
schedule_delayed_work_on(cpu, vmstat_work, HZ + cpu);
}
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index d342e89b8bd..ceadfcf457c 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -174,7 +174,7 @@ static inline int hidp_queue_event(struct hidp_session *session, struct input_de
static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
- struct hid_device *hid = dev->private;
+ struct hid_device *hid = input_get_drvdata(dev);
struct hidp_session *session = hid->driver_data;
return hidp_queue_event(session, dev, type, code, value);
@@ -182,7 +182,7 @@ static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigne
static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
- struct hidp_session *session = dev->private;
+ struct hidp_session *session = input_get_drvdata(dev);
return hidp_queue_event(session, dev, type, code, value);
}
@@ -630,7 +630,7 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co
struct input_dev *input = session->input;
int i;
- input->private = session;
+ input_set_drvdata(input, session);
input->name = "Bluetooth HID Boot Protocol Device";
@@ -663,7 +663,7 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co
input->relbit[0] |= BIT(REL_WHEEL);
}
- input->cdev.dev = hidp_get_device(session);
+ input->dev.parent = hidp_get_device(session);
input->event = hidp_input_event;
@@ -737,10 +737,8 @@ static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_conn
list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
hidp_send_report(session, report);
- if (hidinput_connect(hid) == 0) {
+ if (hidinput_connect(hid) == 0)
hid->claimed |= HID_CLAIMED_INPUT;
- hid_ff_init(hid);
- }
}
int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
@@ -864,7 +862,7 @@ failed:
if (session->hid)
hid_free_device(session->hid);
- kfree(session->input);
+ input_free_device(session->input);
kfree(session);
return err;
}
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index e3c26a9ccad..a5e372b9ec4 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -19,7 +19,6 @@
#include <linux/rtnetlink.h>
#include <linux/jiffies.h>
#include <linux/spinlock.h>
-#include <linux/list.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
@@ -27,8 +26,7 @@
enum lw_bits {
- LW_RUNNING = 0,
- LW_SE_USED
+ LW_URGENT = 0,
};
static unsigned long linkwatch_flags;
@@ -37,17 +35,9 @@ static unsigned long linkwatch_nextevent;
static void linkwatch_event(struct work_struct *dummy);
static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event);
-static LIST_HEAD(lweventlist);
+static struct net_device *lweventlist;
static DEFINE_SPINLOCK(lweventlist_lock);
-struct lw_event {
- struct list_head list;
- struct net_device *dev;
-};
-
-/* Avoid kmalloc() for most systems */
-static struct lw_event singleevent;
-
static unsigned char default_operstate(const struct net_device *dev)
{
if (!netif_carrier_ok(dev))
@@ -87,25 +77,102 @@ static void rfc2863_policy(struct net_device *dev)
}
-/* Must be called with the rtnl semaphore held */
-void linkwatch_run_queue(void)
+static int linkwatch_urgent_event(struct net_device *dev)
{
- struct list_head head, *n, *next;
+ return netif_running(dev) && netif_carrier_ok(dev) &&
+ dev->qdisc != dev->qdisc_sleeping;
+}
+
+
+static void linkwatch_add_event(struct net_device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&lweventlist_lock, flags);
+ dev->link_watch_next = lweventlist;
+ lweventlist = dev;
+ spin_unlock_irqrestore(&lweventlist_lock, flags);
+}
+
+
+static void linkwatch_schedule_work(int urgent)
+{
+ unsigned long delay = linkwatch_nextevent - jiffies;
+
+ if (test_bit(LW_URGENT, &linkwatch_flags))
+ return;
+
+ /* Minimise down-time: drop delay for up event. */
+ if (urgent) {
+ if (test_and_set_bit(LW_URGENT, &linkwatch_flags))
+ return;
+ delay = 0;
+ }
+
+ /* If we wrap around we'll delay it by at most HZ. */
+ if (delay > HZ)
+ delay = 0;
+
+ /*
+ * This is true if we've scheduled it immeditately or if we don't
+ * need an immediate execution and it's already pending.
+ */
+ if (schedule_delayed_work(&linkwatch_work, delay) == !delay)
+ return;
+
+ /* Don't bother if there is nothing urgent. */
+ if (!test_bit(LW_URGENT, &linkwatch_flags))
+ return;
+
+ /* It's already running which is good enough. */
+ if (!cancel_delayed_work(&linkwatch_work))
+ return;
+
+ /* Otherwise we reschedule it again for immediate exection. */
+ schedule_delayed_work(&linkwatch_work, 0);
+}
+
+
+static void __linkwatch_run_queue(int urgent_only)
+{
+ struct net_device *next;
+
+ /*
+ * Limit the number of linkwatch events to one
+ * per second so that a runaway driver does not
+ * cause a storm of messages on the netlink
+ * socket. This limit does not apply to up events
+ * while the device qdisc is down.
+ */
+ if (!urgent_only)
+ linkwatch_nextevent = jiffies + HZ;
+ /* Limit wrap-around effect on delay. */
+ else if (time_after(linkwatch_nextevent, jiffies + HZ))
+ linkwatch_nextevent = jiffies;
+
+ clear_bit(LW_URGENT, &linkwatch_flags);
spin_lock_irq(&lweventlist_lock);
- list_replace_init(&lweventlist, &head);
+ next = lweventlist;
+ lweventlist = NULL;
spin_unlock_irq(&lweventlist_lock);
- list_for_each_safe(n, next, &head) {
- struct lw_event *event = list_entry(n, struct lw_event, list);
- struct net_device *dev = event->dev;
+ while (next) {
+ struct net_device *dev = next;
- if (event == &singleevent) {
- clear_bit(LW_SE_USED, &linkwatch_flags);
- } else {
- kfree(event);
+ next = dev->link_watch_next;
+
+ if (urgent_only && !linkwatch_urgent_event(dev)) {
+ linkwatch_add_event(dev);
+ continue;
}
+ /*
+ * Make sure the above read is complete since it can be
+ * rewritten as soon as we clear the bit below.
+ */
+ smp_mb__before_clear_bit();
+
/* We are about to handle this device,
* so new events can be accepted
*/
@@ -124,58 +191,39 @@ void linkwatch_run_queue(void)
dev_put(dev);
}
+
+ if (lweventlist)
+ linkwatch_schedule_work(0);
}
-static void linkwatch_event(struct work_struct *dummy)
+/* Must be called with the rtnl semaphore held */
+void linkwatch_run_queue(void)
{
- /* Limit the number of linkwatch events to one
- * per second so that a runaway driver does not
- * cause a storm of messages on the netlink
- * socket
- */
- linkwatch_nextevent = jiffies + HZ;
- clear_bit(LW_RUNNING, &linkwatch_flags);
+ __linkwatch_run_queue(0);
+}
+
+static void linkwatch_event(struct work_struct *dummy)
+{
rtnl_lock();
- linkwatch_run_queue();
+ __linkwatch_run_queue(time_after(linkwatch_nextevent, jiffies));
rtnl_unlock();
}
void linkwatch_fire_event(struct net_device *dev)
{
- if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) {
- unsigned long flags;
- struct lw_event *event;
-
- if (test_and_set_bit(LW_SE_USED, &linkwatch_flags)) {
- event = kmalloc(sizeof(struct lw_event), GFP_ATOMIC);
-
- if (unlikely(event == NULL)) {
- clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
- return;
- }
- } else {
- event = &singleevent;
- }
+ int urgent = linkwatch_urgent_event(dev);
+ if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) {
dev_hold(dev);
- event->dev = dev;
-
- spin_lock_irqsave(&lweventlist_lock, flags);
- list_add_tail(&event->list, &lweventlist);
- spin_unlock_irqrestore(&lweventlist_lock, flags);
- if (!test_and_set_bit(LW_RUNNING, &linkwatch_flags)) {
- unsigned long delay = linkwatch_nextevent - jiffies;
+ linkwatch_add_event(dev);
+ } else if (!urgent)
+ return;
- /* If we wrap around we'll delay it by at most HZ. */
- if (delay > HZ)
- delay = 0;
- schedule_delayed_work(&linkwatch_work, delay);
- }
- }
+ linkwatch_schedule_work(urgent);
}
EXPORT_SYMBOL(linkwatch_fire_event);
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 7edea2a1696..75c02306253 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -15,128 +15,34 @@ MODULE_DESCRIPTION("arptables filter table");
#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
(1 << NF_ARP_FORWARD))
-/* Standard entry. */
-struct arpt_standard
-{
- struct arpt_entry entry;
- struct arpt_standard_target target;
-};
-
-struct arpt_error_target
-{
- struct arpt_entry_target target;
- char errorname[ARPT_FUNCTION_MAXNAMELEN];
-};
-
-struct arpt_error
-{
- struct arpt_entry entry;
- struct arpt_error_target target;
-};
-
static struct
{
struct arpt_replace repl;
struct arpt_standard entries[3];
struct arpt_error term;
-} initial_table __initdata
-= { { "filter", FILTER_VALID_HOOKS, 4,
- sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error),
- { [NF_ARP_IN] = 0,
- [NF_ARP_OUT] = sizeof(struct arpt_standard),
- [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), },
- { [NF_ARP_IN] = 0,
- [NF_ARP_OUT] = sizeof(struct arpt_standard),
- [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard), },
- 0, NULL, { } },
- {
- /* ARP_IN */
- {
- {
- {
- { 0 }, { 0 }, { 0 }, { 0 },
- 0, 0,
- { { 0, }, { 0, } },
- { { 0, }, { 0, } },
- 0, 0,
- 0, 0,
- 0, 0,
- "", "", { 0 }, { 0 },
- 0, 0
- },
- sizeof(struct arpt_entry),
- sizeof(struct arpt_standard),
- 0,
- { 0, 0 }, { } },
- { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 }
- },
- /* ARP_OUT */
- {
- {
- {
- { 0 }, { 0 }, { 0 }, { 0 },
- 0, 0,
- { { 0, }, { 0, } },
- { { 0, }, { 0, } },
- 0, 0,
- 0, 0,
- 0, 0,
- "", "", { 0 }, { 0 },
- 0, 0
- },
- sizeof(struct arpt_entry),
- sizeof(struct arpt_standard),
- 0,
- { 0, 0 }, { } },
- { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 }
- },
- /* ARP_FORWARD */
- {
- {
- {
- { 0 }, { 0 }, { 0 }, { 0 },
- 0, 0,
- { { 0, }, { 0, } },
- { { 0, }, { 0, } },
- 0, 0,
- 0, 0,
- 0, 0,
- "", "", { 0 }, { 0 },
- 0, 0
- },
- sizeof(struct arpt_entry),
- sizeof(struct arpt_standard),
- 0,
- { 0, 0 }, { } },
- { { { { ARPT_ALIGN(sizeof(struct arpt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 }
- }
- },
- /* ERROR */
- {
- {
- {
- { 0 }, { 0 }, { 0 }, { 0 },
- 0, 0,
- { { 0, }, { 0, } },
- { { 0, }, { 0, } },
- 0, 0,
- 0, 0,
- 0, 0,
- "", "", { 0 }, { 0 },
- 0, 0
- },
- sizeof(struct arpt_entry),
- sizeof(struct arpt_error),
- 0,
- { 0, 0 }, { } },
- { { { { ARPT_ALIGN(sizeof(struct arpt_error_target)), ARPT_ERROR_TARGET } },
- { } },
- "ERROR"
- }
- }
+} initial_table __initdata = {
+ .repl = {
+ .name = "filter",
+ .valid_hooks = FILTER_VALID_HOOKS,
+ .num_entries = 4,
+ .size = sizeof(struct arpt_standard) * 3 + sizeof(struct arpt_error),
+ .hook_entry = {
+ [NF_ARP_IN] = 0,
+ [NF_ARP_OUT] = sizeof(struct arpt_standard),
+ [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard),
+ },
+ .underflow = {
+ [NF_ARP_IN] = 0,
+ [NF_ARP_OUT] = sizeof(struct arpt_standard),
+ [NF_ARP_FORWARD] = 2 * sizeof(struct arpt_standard),
+ },
+ },
+ .entries = {
+ ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_IN */
+ ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_OUT */
+ ARPT_STANDARD_INIT(NF_ACCEPT), /* ARP_FORWARD */
+ },
+ .term = ARPT_ERROR_INIT,
};
static struct arpt_table packet_filter = {
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 42728909eba..4f51c1d7d2d 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -26,53 +26,29 @@ static struct
struct ipt_replace repl;
struct ipt_standard entries[3];
struct ipt_error term;
-} initial_table __initdata
-= { { "filter", FILTER_VALID_HOOKS, 4,
- sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
- { [NF_IP_LOCAL_IN] = 0,
- [NF_IP_FORWARD] = sizeof(struct ipt_standard),
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
- { [NF_IP_LOCAL_IN] = 0,
- [NF_IP_FORWARD] = sizeof(struct ipt_standard),
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
- 0, NULL, { } },
- {
- /* LOCAL_IN */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* FORWARD */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* LOCAL_OUT */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } }
- },
- /* ERROR */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_error),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
- { } },
- "ERROR"
- }
- }
+} initial_table __initdata = {
+ .repl = {
+ .name = "filter",
+ .valid_hooks = FILTER_VALID_HOOKS,
+ .num_entries = 4,
+ .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
+ .hook_entry = {
+ [NF_IP_LOCAL_IN] = 0,
+ [NF_IP_FORWARD] = sizeof(struct ipt_standard),
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
+ },
+ .underflow = {
+ [NF_IP_LOCAL_IN] = 0,
+ [NF_IP_FORWARD] = sizeof(struct ipt_standard),
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
+ },
+ },
+ .entries = {
+ IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
+ },
+ .term = IPT_ERROR_INIT, /* ERROR */
};
static struct xt_table packet_filter = {
@@ -105,7 +81,8 @@ ipt_local_out_hook(unsigned int hook,
if ((*pskb)->len < sizeof(struct iphdr)
|| ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
if (net_ratelimit())
- printk("ipt_hook: happy cracking.\n");
+ printk("iptable_filter: ignoring short SOCK_RAW "
+ "packet.\n");
return NF_ACCEPT;
}
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 9278802f274..902446f7cbc 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -33,73 +33,35 @@ static struct
struct ipt_replace repl;
struct ipt_standard entries[5];
struct ipt_error term;
-} initial_table __initdata
-= { { "mangle", MANGLE_VALID_HOOKS, 6,
- sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error),
- { [NF_IP_PRE_ROUTING] = 0,
- [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard),
- [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2,
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3,
- [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 },
- { [NF_IP_PRE_ROUTING] = 0,
- [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard),
- [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2,
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3,
- [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4 },
- 0, NULL, { } },
- {
- /* PRE_ROUTING */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* LOCAL_IN */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* FORWARD */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* LOCAL_OUT */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* POST_ROUTING */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- },
- /* ERROR */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_error),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
- { } },
- "ERROR"
- }
- }
+} initial_table __initdata = {
+ .repl = {
+ .name = "mangle",
+ .valid_hooks = MANGLE_VALID_HOOKS,
+ .num_entries = 6,
+ .size = sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error),
+ .hook_entry = {
+ [NF_IP_PRE_ROUTING] = 0,
+ [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard),
+ [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2,
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3,
+ [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4,
+ },
+ .underflow = {
+ [NF_IP_PRE_ROUTING] = 0,
+ [NF_IP_LOCAL_IN] = sizeof(struct ipt_standard),
+ [NF_IP_FORWARD] = sizeof(struct ipt_standard) * 2,
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 3,
+ [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard) * 4,
+ },
+ },
+ .entries = {
+ IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
+ },
+ .term = IPT_ERROR_INIT, /* ERROR */
};
static struct xt_table packet_mangler = {
@@ -138,7 +100,8 @@ ipt_local_hook(unsigned int hook,
if ((*pskb)->len < sizeof(struct iphdr)
|| ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
if (net_ratelimit())
- printk("ipt_hook: happy cracking.\n");
+ printk("iptable_mangle: ignoring short SOCK_RAW "
+ "packet.\n");
return NF_ACCEPT;
}
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 18c3d4c9ff5..d6e50339568 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -5,6 +5,7 @@
*/
#include <linux/module.h>
#include <linux/netfilter_ipv4/ip_tables.h>
+#include <net/ip.h>
#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
@@ -21,62 +22,18 @@ static struct
.size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
.hook_entry = {
[NF_IP_PRE_ROUTING] = 0,
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard)
+ },
.underflow = {
[NF_IP_PRE_ROUTING] = 0,
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard)
+ },
},
.entries = {
- /* PRE_ROUTING */
- {
- .entry = {
- .target_offset = sizeof(struct ipt_entry),
- .next_offset = sizeof(struct ipt_standard),
- },
- .target = {
- .target = {
- .u = {
- .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
- },
- },
- .verdict = -NF_ACCEPT - 1,
- },
- },
-
- /* LOCAL_OUT */
- {
- .entry = {
- .target_offset = sizeof(struct ipt_entry),
- .next_offset = sizeof(struct ipt_standard),
- },
- .target = {
- .target = {
- .u = {
- .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
- },
- },
- .verdict = -NF_ACCEPT - 1,
- },
- },
+ IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
},
- /* ERROR */
- .term = {
- .entry = {
- .target_offset = sizeof(struct ipt_entry),
- .next_offset = sizeof(struct ipt_error),
- },
- .target = {
- .target = {
- .u = {
- .user = {
- .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)),
- .name = IPT_ERROR_TARGET,
- },
- },
- },
- .errorname = "ERROR",
- },
- }
+ .term = IPT_ERROR_INIT, /* ERROR */
};
static struct xt_table packet_raw = {
@@ -98,6 +55,24 @@ ipt_hook(unsigned int hook,
return ipt_do_table(pskb, hook, in, out, &packet_raw);
}
+static unsigned int
+ipt_local_hook(unsigned int hook,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr) ||
+ ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+ if (net_ratelimit())
+ printk("iptable_raw: ignoring short SOCK_RAW"
+ "packet.\n");
+ return NF_ACCEPT;
+ }
+ return ipt_do_table(pskb, hook, in, out, &packet_raw);
+}
+
/* 'raw' is the very first table. */
static struct nf_hook_ops ipt_ops[] = {
{
@@ -108,7 +83,7 @@ static struct nf_hook_ops ipt_ops[] = {
.owner = THIS_MODULE,
},
{
- .hook = ipt_hook,
+ .hook = ipt_local_hook,
.pf = PF_INET,
.hooknum = NF_IP_LOCAL_OUT,
.priority = NF_IP_PRI_RAW,
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 2534f718ab9..6740736c5e7 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -46,77 +46,20 @@ static struct
.hook_entry = {
[NF_IP_PRE_ROUTING] = 0,
[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
+ },
.underflow = {
[NF_IP_PRE_ROUTING] = 0,
[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
- [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
+ },
},
.entries = {
- /* PRE_ROUTING */
- {
- .entry = {
- .target_offset = sizeof(struct ipt_entry),
- .next_offset = sizeof(struct ipt_standard),
- },
- .target = {
- .target = {
- .u = {
- .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
- },
- },
- .verdict = -NF_ACCEPT - 1,
- },
- },
- /* POST_ROUTING */
- {
- .entry = {
- .target_offset = sizeof(struct ipt_entry),
- .next_offset = sizeof(struct ipt_standard),
- },
- .target = {
- .target = {
- .u = {
- .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
- },
- },
- .verdict = -NF_ACCEPT - 1,
- },
- },
- /* LOCAL_OUT */
- {
- .entry = {
- .target_offset = sizeof(struct ipt_entry),
- .next_offset = sizeof(struct ipt_standard),
- },
- .target = {
- .target = {
- .u = {
- .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
- },
- },
- .verdict = -NF_ACCEPT - 1,
- },
- },
+ IPT_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
+ IPT_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
},
- /* ERROR */
- .term = {
- .entry = {
- .target_offset = sizeof(struct ipt_entry),
- .next_offset = sizeof(struct ipt_error),
- },
- .target = {
- .target = {
- .u = {
- .user = {
- .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)),
- .name = IPT_ERROR_TARGET,
- },
- },
- },
- .errorname = "ERROR",
- },
- }
+ .term = IPT_ERROR_INIT, /* ERROR */
};
static struct xt_table nat_table = {
@@ -230,9 +173,7 @@ static int ipt_dnat_checkentry(const char *tablename,
}
inline unsigned int
-alloc_null_binding(struct nf_conn *ct,
- struct nf_nat_info *info,
- unsigned int hooknum)
+alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
{
/* Force range to this IP; let proto decide mapping for
per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED).
@@ -251,9 +192,7 @@ alloc_null_binding(struct nf_conn *ct,
}
unsigned int
-alloc_null_binding_confirmed(struct nf_conn *ct,
- struct nf_nat_info *info,
- unsigned int hooknum)
+alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
{
__be32 ip
= (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
@@ -275,8 +214,7 @@ int nf_nat_rule_find(struct sk_buff **pskb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
- struct nf_conn *ct,
- struct nf_nat_info *info)
+ struct nf_conn *ct)
{
int ret;
@@ -285,7 +223,7 @@ int nf_nat_rule_find(struct sk_buff **pskb,
if (ret == NF_ACCEPT) {
if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
/* NUL mapping */
- ret = alloc_null_binding(ct, info, hooknum);
+ ret = alloc_null_binding(ct, hooknum);
}
return ret;
}
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 64bbed2ba78..55dac36dbc8 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -80,7 +80,6 @@ nf_nat_fn(unsigned int hooknum,
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
struct nf_conn_nat *nat;
- struct nf_nat_info *info;
/* maniptype == SRC for postrouting. */
enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
@@ -129,7 +128,6 @@ nf_nat_fn(unsigned int hooknum,
}
/* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
case IP_CT_NEW:
- info = &nat->info;
/* Seen it before? This can happen for loopback, retrans,
or local packets.. */
@@ -138,14 +136,13 @@ nf_nat_fn(unsigned int hooknum,
if (unlikely(nf_ct_is_confirmed(ct)))
/* NAT module was loaded late */
- ret = alloc_null_binding_confirmed(ct, info,
- hooknum);
+ ret = alloc_null_binding_confirmed(ct, hooknum);
else if (hooknum == NF_IP_LOCAL_IN)
/* LOCAL_IN hook doesn't have a chain! */
- ret = alloc_null_binding(ct, info, hooknum);
+ ret = alloc_null_binding(ct, hooknum);
else
ret = nf_nat_rule_find(pskb, hooknum, in, out,
- ct, info);
+ ct);
if (ret != NF_ACCEPT) {
return ret;
@@ -160,10 +157,8 @@ nf_nat_fn(unsigned int hooknum,
/* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY));
- info = &nat->info;
}
- NF_CT_ASSERT(info);
return nf_nat_packet(ct, ctinfo, hooknum, pskb);
}
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 66026df1cc7..4c7e95fa090 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -118,15 +118,15 @@ static int udp_port_rover;
* Note about this hash function :
* Typical use is probably daddr = 0, only dport is going to vary hash
*/
-static inline unsigned int hash_port_and_addr(__u16 port, __be32 addr)
+static inline unsigned int udp_hash_port(__u16 port)
{
- addr ^= addr >> 16;
- addr ^= addr >> 8;
- return port ^ addr;
+ return port;
}
static inline int __udp_lib_port_inuse(unsigned int hash, int port,
- __be32 daddr, struct hlist_head udptable[])
+ const struct sock *this_sk,
+ struct hlist_head udptable[],
+ const struct udp_get_port_ops *ops)
{
struct sock *sk;
struct hlist_node *node;
@@ -138,7 +138,10 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port,
inet = inet_sk(sk);
if (inet->num != port)
continue;
- if (inet->rcv_saddr == daddr)
+ if (this_sk) {
+ if (ops->saddr_cmp(sk, this_sk))
+ return 1;
+ } else if (ops->saddr_any(sk))
return 1;
}
return 0;
@@ -151,12 +154,11 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port,
* @snum: port number to look up
* @udptable: hash list table, must be of UDP_HTABLE_SIZE
* @port_rover: pointer to record of last unallocated port
- * @saddr_comp: AF-dependent comparison of bound local IP addresses
+ * @ops: AF-dependent address operations
*/
int __udp_lib_get_port(struct sock *sk, unsigned short snum,
struct hlist_head udptable[], int *port_rover,
- int (*saddr_comp)(const struct sock *sk1,
- const struct sock *sk2 ) )
+ const struct udp_get_port_ops *ops)
{
struct hlist_node *node;
struct hlist_head *head;
@@ -176,8 +178,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
int size;
- hash = hash_port_and_addr(result,
- inet_sk(sk)->rcv_saddr);
+ hash = ops->hash_port_and_rcv_saddr(result, sk);
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
if (hlist_empty(head)) {
if (result > sysctl_local_port_range[1])
@@ -203,17 +204,16 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
result = sysctl_local_port_range[0]
+ ((result - sysctl_local_port_range[0]) &
(UDP_HTABLE_SIZE - 1));
- hash = hash_port_and_addr(result, 0);
+ hash = udp_hash_port(result);
if (__udp_lib_port_inuse(hash, result,
- 0, udptable))
+ NULL, udptable, ops))
continue;
- if (!inet_sk(sk)->rcv_saddr)
+ if (ops->saddr_any(sk))
break;
- hash = hash_port_and_addr(result,
- inet_sk(sk)->rcv_saddr);
+ hash = ops->hash_port_and_rcv_saddr(result, sk);
if (! __udp_lib_port_inuse(hash, result,
- inet_sk(sk)->rcv_saddr, udptable))
+ sk, udptable, ops))
break;
}
if (i >= (1 << 16) / UDP_HTABLE_SIZE)
@@ -221,7 +221,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
gotit:
*port_rover = snum = result;
} else {
- hash = hash_port_and_addr(snum, 0);
+ hash = udp_hash_port(snum);
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
sk_for_each(sk2, node, head)
@@ -231,12 +231,11 @@ gotit:
(!sk2->sk_reuse || !sk->sk_reuse) &&
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if ||
sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
- (*saddr_comp)(sk, sk2))
+ ops->saddr_cmp(sk, sk2))
goto fail;
- if (inet_sk(sk)->rcv_saddr) {
- hash = hash_port_and_addr(snum,
- inet_sk(sk)->rcv_saddr);
+ if (!ops->saddr_any(sk)) {
+ hash = ops->hash_port_and_rcv_saddr(snum, sk);
head = &udptable[hash & (UDP_HTABLE_SIZE - 1)];
sk_for_each(sk2, node, head)
@@ -248,7 +247,7 @@ gotit:
!sk->sk_bound_dev_if ||
sk2->sk_bound_dev_if ==
sk->sk_bound_dev_if) &&
- (*saddr_comp)(sk, sk2))
+ ops->saddr_cmp(sk, sk2))
goto fail;
}
}
@@ -266,12 +265,12 @@ fail:
}
int udp_get_port(struct sock *sk, unsigned short snum,
- int (*scmp)(const struct sock *, const struct sock *))
+ const struct udp_get_port_ops *ops)
{
- return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
+ return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops);
}
-int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
+static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
{
struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
@@ -280,9 +279,33 @@ int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
inet1->rcv_saddr == inet2->rcv_saddr ));
}
+static int ipv4_rcv_saddr_any(const struct sock *sk)
+{
+ return !inet_sk(sk)->rcv_saddr;
+}
+
+static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr)
+{
+ addr ^= addr >> 16;
+ addr ^= addr >> 8;
+ return port ^ addr;
+}
+
+static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port,
+ const struct sock *sk)
+{
+ return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr);
+}
+
+const struct udp_get_port_ops udp_ipv4_ops = {
+ .saddr_cmp = ipv4_rcv_saddr_equal,
+ .saddr_any = ipv4_rcv_saddr_any,
+ .hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr,
+};
+
static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
{
- return udp_get_port(sk, snum, ipv4_rcv_saddr_equal);
+ return udp_get_port(sk, snum, &udp_ipv4_ops);
}
/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
@@ -297,8 +320,8 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
unsigned int hash, hashwild;
int score, best = -1, hport = ntohs(dport);
- hash = hash_port_and_addr(hport, daddr);
- hashwild = hash_port_and_addr(hport, 0);
+ hash = ipv4_hash_port_and_addr(hport, daddr);
+ hashwild = udp_hash_port(hport);
read_lock(&udp_hash_lock);
@@ -1198,8 +1221,8 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
struct sock *sk, *skw, *sknext;
int dif;
int hport = ntohs(uh->dest);
- unsigned int hash = hash_port_and_addr(hport, daddr);
- unsigned int hashwild = hash_port_and_addr(hport, 0);
+ unsigned int hash = ipv4_hash_port_and_addr(hport, daddr);
+ unsigned int hashwild = udp_hash_port(hport);
dif = skb->dev->ifindex;
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
index 820a477cfaa..06d94195e64 100644
--- a/net/ipv4/udp_impl.h
+++ b/net/ipv4/udp_impl.h
@@ -5,14 +5,14 @@
#include <net/protocol.h>
#include <net/inet_common.h>
+extern const struct udp_get_port_ops udp_ipv4_ops;
+
extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int );
extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []);
extern int __udp_lib_get_port(struct sock *sk, unsigned short snum,
struct hlist_head udptable[], int *port_rover,
- int (*)(const struct sock*,const struct sock*));
-extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
-
+ const struct udp_get_port_ops *ops);
extern int udp_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen);
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index f34fd686a8f..3653b32dce2 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -19,14 +19,15 @@ struct hlist_head udplite_hash[UDP_HTABLE_SIZE];
static int udplite_port_rover;
int udplite_get_port(struct sock *sk, unsigned short p,
- int (*c)(const struct sock *, const struct sock *))
+ const struct udp_get_port_ops *ops)
{
- return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c);
+ return __udp_lib_get_port(sk, p, udplite_hash,
+ &udplite_port_rover, ops);
}
static int udplite_v4_get_port(struct sock *sk, unsigned short snum)
{
- return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal);
+ return udplite_get_port(sk, snum, &udp_ipv4_ops);
}
static int udplite_rcv(struct sk_buff *skb)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d02685c6bc6..c7ea248fae2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4204,6 +4204,10 @@ int __init addrconf_init(void)
return err;
ip6_null_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+ ip6_prohibit_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+ ip6_blk_hole_entry.rt6i_idev = in6_dev_get(&loopback_dev);
+#endif
register_netdevice_notifier(&ipv6_dev_notf);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 6d8e4ac7bda..14be0b9b77a 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -660,6 +660,14 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
Hop-by-hop options.
**********************************/
+/*
+ * Note: we cannot rely on skb->dst before we assign it in ip6_route_input().
+ */
+static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
+{
+ return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev);
+}
+
/* Router Alert as of RFC 2711 */
static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
@@ -688,25 +696,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
nh[optoff+1]);
- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
+ IP6_INC_STATS_BH(ipv6_skb_idev(skb),
IPSTATS_MIB_INHDRERRORS);
goto drop;
}
pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
if (pkt_len <= IPV6_MAXPLEN) {
- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
+ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
return 0;
}
if (ipv6_hdr(skb)->payload_len) {
- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
+ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
return 0;
}
if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
- IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS);
+ IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS);
goto drop;
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index f508171bab7..4704b5fc308 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -463,10 +463,17 @@ int ip6_forward(struct sk_buff *skb)
*/
if (xrlim_allow(dst, 1*HZ))
ndisc_send_redirect(skb, n, target);
- } else if (ipv6_addr_type(&hdr->saddr)&(IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK
- |IPV6_ADDR_LINKLOCAL)) {
+ } else {
+ int addrtype = ipv6_addr_type(&hdr->saddr);
+
/* This check is security critical. */
- goto error;
+ if (addrtype & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LOOPBACK))
+ goto error;
+ if (addrtype & IPV6_ADDR_LINKLOCAL) {
+ icmpv6_send(skb, ICMPV6_DEST_UNREACH,
+ ICMPV6_NOT_NEIGHBOUR, 0, skb->dev);
+ goto error;
+ }
}
if (skb->len > dst_mtu(dst)) {
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 76f0cf66f95..7e32e2aaf7f 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -24,53 +24,29 @@ static struct
struct ip6t_replace repl;
struct ip6t_standard entries[3];
struct ip6t_error term;
-} initial_table __initdata
-= { { "filter", FILTER_VALID_HOOKS, 4,
- sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
- { [NF_IP6_LOCAL_IN] = 0,
- [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
- [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 },
- { [NF_IP6_LOCAL_IN] = 0,
- [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
- [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 },
- 0, NULL, { } },
- {
- /* LOCAL_IN */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* FORWARD */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* LOCAL_OUT */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } }
- },
- /* ERROR */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_error),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
- { } },
- "ERROR"
- }
- }
+} initial_table __initdata = {
+ .repl = {
+ .name = "filter",
+ .valid_hooks = FILTER_VALID_HOOKS,
+ .num_entries = 4,
+ .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
+ .hook_entry = {
+ [NF_IP6_LOCAL_IN] = 0,
+ [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
+ [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
+ },
+ .underflow = {
+ [NF_IP6_LOCAL_IN] = 0,
+ [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
+ [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
+ },
+ },
+ .entries = {
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
+ },
+ .term = IP6T_ERROR_INIT, /* ERROR */
};
static struct xt_table packet_filter = {
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index a9f10e32c16..f2d26495f41 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -32,73 +32,35 @@ static struct
struct ip6t_replace repl;
struct ip6t_standard entries[5];
struct ip6t_error term;
-} initial_table __initdata
-= { { "mangle", MANGLE_VALID_HOOKS, 6,
- sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
- { [NF_IP6_PRE_ROUTING] = 0,
- [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard),
- [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2,
- [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
- [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4},
- { [NF_IP6_PRE_ROUTING] = 0,
- [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard),
- [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2,
- [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
- [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4},
- 0, NULL, { } },
- {
- /* PRE_ROUTING */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* LOCAL_IN */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* FORWARD */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* LOCAL_OUT */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* POST_ROUTING */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_standard),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } }
- },
- /* ERROR */
- { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ip6t_entry),
- sizeof(struct ip6t_error),
- 0, { 0, 0 }, { } },
- { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
- { } },
- "ERROR"
- }
- }
+} initial_table __initdata = {
+ .repl = {
+ .name = "mangle",
+ .valid_hooks = MANGLE_VALID_HOOKS,
+ .num_entries = 6,
+ .size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
+ .hook_entry = {
+ [NF_IP6_PRE_ROUTING] = 0,
+ [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard),
+ [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2,
+ [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
+ [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
+ },
+ .underflow = {
+ [NF_IP6_PRE_ROUTING] = 0,
+ [NF_IP6_LOCAL_IN] = sizeof(struct ip6t_standard),
+ [NF_IP6_FORWARD] = sizeof(struct ip6t_standard) * 2,
+ [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 3,
+ [NF_IP6_POST_ROUTING] = sizeof(struct ip6t_standard) * 4,
+ },
+ },
+ .entries = {
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_IN */
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* FORWARD */
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
+ },
+ .term = IP6T_ERROR_INIT, /* ERROR */
};
static struct xt_table packet_mangler = {
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index a3eb5b8ce18..0acda45d455 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -35,56 +35,10 @@ static struct
},
},
.entries = {
- /* PRE_ROUTING */
- {
- .entry = {
- .target_offset = sizeof(struct ip6t_entry),
- .next_offset = sizeof(struct ip6t_standard),
- },
- .target = {
- .target = {
- .u = {
- .target_size = IP6T_ALIGN(sizeof(struct ip6t_standard_target)),
- },
- },
- .verdict = -NF_ACCEPT - 1,
- },
- },
-
- /* LOCAL_OUT */
- {
- .entry = {
- .target_offset = sizeof(struct ip6t_entry),
- .next_offset = sizeof(struct ip6t_standard),
- },
- .target = {
- .target = {
- .u = {
- .target_size = IP6T_ALIGN(sizeof(struct ip6t_standard_target)),
- },
- },
- .verdict = -NF_ACCEPT - 1,
- },
- },
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */
+ IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */
},
- /* ERROR */
- .term = {
- .entry = {
- .target_offset = sizeof(struct ip6t_entry),
- .next_offset = sizeof(struct ip6t_error),
- },
- .target = {
- .target = {
- .u = {
- .user = {
- .target_size = IP6T_ALIGN(sizeof(struct ip6t_error_target)),
- .name = IP6T_ERROR_TARGET,
- },
- },
- },
- .errorname = "ERROR",
- },
- }
+ .term = IP6T_ERROR_INIT, /* ERROR */
};
static struct xt_table packet_raw = {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b083c09e3d2..a7ae59c954d 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -52,9 +52,28 @@
DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
+static int ipv6_rcv_saddr_any(const struct sock *sk)
+{
+ struct ipv6_pinfo *np = inet6_sk(sk);
+
+ return ipv6_addr_any(&np->rcv_saddr);
+}
+
+static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port,
+ const struct sock *sk)
+{
+ return port;
+}
+
+const struct udp_get_port_ops udp_ipv6_ops = {
+ .saddr_cmp = ipv6_rcv_saddr_equal,
+ .saddr_any = ipv6_rcv_saddr_any,
+ .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr,
+};
+
static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
{
- return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
+ return udp_get_port(sk, snum, &udp_ipv6_ops);
}
static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 6e252f318f7..36b0c11a28a 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -6,6 +6,8 @@
#include <net/addrconf.h>
#include <net/inet_common.h>
+extern const struct udp_get_port_ops udp_ipv6_ops;
+
extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
int , int , int , __be32 , struct hlist_head []);
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index f54016a5500..c40a51362f8 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = {
static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
{
- return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
+ return udplite_get_port(sk, snum, &udp_ipv6_ops);
}
struct proto udplitev6_prot = {
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 822917debef..3e07e9d6fa4 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -17,6 +17,7 @@
* scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
* SSID)
*/
+#include <linux/delay.h>
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
@@ -27,7 +28,6 @@
#include <linux/rtnetlink.h>
#include <net/iw_handler.h>
#include <asm/types.h>
-#include <asm/delay.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index e132c8ae878..e8b5c2d7db6 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -299,7 +299,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
{
struct nf_conn *ct = (struct nf_conn *)nfct;
struct nf_conn_help *help = nfct_help(ct);
- struct nf_conntrack_l3proto *l3proto;
struct nf_conntrack_l4proto *l4proto;
typeof(nf_conntrack_destroyed) destroyed;
@@ -317,10 +316,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
* destroy_conntrack() MUST NOT be called with a write lock
* to nf_conntrack_lock!!! -HW */
rcu_read_lock();
- l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num);
- if (l3proto && l3proto->destroy)
- l3proto->destroy(ct);
-
l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num,
ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
if (l4proto && l4proto->destroy)
@@ -893,8 +888,13 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
NF_CT_DUMP_TUPLE(newreply);
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
- if (!ct->master && help && help->expecting == 0)
- help->helper = __nf_ct_helper_find(newreply);
+ if (!ct->master && help && help->expecting == 0) {
+ struct nf_conntrack_helper *helper;
+ helper = __nf_ct_helper_find(newreply);
+ if (helper)
+ memset(&help->help, 0, sizeof(help->help));
+ help->helper = helper;
+ }
write_unlock_bh(&nf_conntrack_lock);
}
EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index aa1a97ee514..d6d39e24132 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -830,11 +830,6 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
char *helpname;
int err;
- if (!help) {
- /* FIXME: we need to reallocate and rehash */
- return -EBUSY;
- }
-
/* don't change helper of sibling connections */
if (ct->master)
return -EINVAL;
@@ -843,25 +838,34 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
if (err < 0)
return err;
- helper = __nf_conntrack_helper_find_byname(helpname);
- if (!helper) {
- if (!strcmp(helpname, ""))
- helper = NULL;
- else
- return -EINVAL;
- }
-
- if (help->helper) {
- if (!helper) {
+ if (!strcmp(helpname, "")) {
+ if (help && help->helper) {
/* we had a helper before ... */
nf_ct_remove_expectations(ct);
help->helper = NULL;
- } else {
- /* need to zero data of old helper */
- memset(&help->help, 0, sizeof(help->help));
}
+
+ return 0;
}
+ if (!help) {
+ /* FIXME: we need to reallocate and rehash */
+ return -EBUSY;
+ }
+
+ helper = __nf_conntrack_helper_find_byname(helpname);
+ if (helper == NULL)
+ return -EINVAL;
+
+ if (help->helper == helper)
+ return 0;
+
+ if (help->helper)
+ /* we had a helper before ... */
+ nf_ct_remove_expectations(ct);
+
+ /* need to zero data of old helper */
+ memset(&help->help, 0, sizeof(help->help));
help->helper = helper;
return 0;
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index f4ea8fe07a5..189ded5f378 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -134,12 +134,66 @@ static void destroy(const struct xt_match *match, void *matchinfo)
nf_ct_l3proto_module_put(match->family);
}
+#ifdef CONFIG_COMPAT
+struct compat_xt_conntrack_info
+{
+ compat_uint_t statemask;
+ compat_uint_t statusmask;
+ struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
+ struct in_addr sipmsk[IP_CT_DIR_MAX];
+ struct in_addr dipmsk[IP_CT_DIR_MAX];
+ compat_ulong_t expires_min;
+ compat_ulong_t expires_max;
+ u_int8_t flags;
+ u_int8_t invflags;
+};
+
+static void compat_from_user(void *dst, void *src)
+{
+ struct compat_xt_conntrack_info *cm = src;
+ struct xt_conntrack_info m = {
+ .statemask = cm->statemask,
+ .statusmask = cm->statusmask,
+ .expires_min = cm->expires_min,
+ .expires_max = cm->expires_max,
+ .flags = cm->flags,
+ .invflags = cm->invflags,
+ };
+ memcpy(m.tuple, cm->tuple, sizeof(m.tuple));
+ memcpy(m.sipmsk, cm->sipmsk, sizeof(m.sipmsk));
+ memcpy(m.dipmsk, cm->dipmsk, sizeof(m.dipmsk));
+ memcpy(dst, &m, sizeof(m));
+}
+
+static int compat_to_user(void __user *dst, void *src)
+{
+ struct xt_conntrack_info *m = src;
+ struct compat_xt_conntrack_info cm = {
+ .statemask = m->statemask,
+ .statusmask = m->statusmask,
+ .expires_min = m->expires_min,
+ .expires_max = m->expires_max,
+ .flags = m->flags,
+ .invflags = m->invflags,
+ };
+ memcpy(cm.tuple, m->tuple, sizeof(cm.tuple));
+ memcpy(cm.sipmsk, m->sipmsk, sizeof(cm.sipmsk));
+ memcpy(cm.dipmsk, m->dipmsk, sizeof(cm.dipmsk));
+ return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
+}
+#endif
+
static struct xt_match conntrack_match = {
.name = "conntrack",
.match = match,
.checkentry = checkentry,
.destroy = destroy,
.matchsize = sizeof(struct xt_conntrack_info),
+#ifdef CONFIG_COMPAT
+ .compatsize = sizeof(struct compat_xt_conntrack_info),
+ .compat_from_user = compat_from_user,
+ .compat_to_user = compat_to_user,
+#endif
.family = AF_INET,
.me = THIS_MODULE,
};
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 3385ee59254..f28bb2dc58d 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -71,12 +71,9 @@ void qdisc_unlock_tree(struct net_device *dev)
/* Kick device.
- Note, that this procedure can be called by a watchdog timer, so that
- we do not check dev->tbusy flag here.
- Returns: 0 - queue is empty.
- >0 - queue is not empty, but throttled.
- <0 - queue is not empty. Device is throttled, if dev->tbusy != 0.
+ Returns: 0 - queue is empty or throttled.
+ >0 - queue is not empty.
NOTE: Called under dev->queue_lock with locally disabled BH.
*/
@@ -115,7 +112,7 @@ static inline int qdisc_restart(struct net_device *dev)
kfree_skb(skb);
if (net_ratelimit())
printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name);
- return -1;
+ goto out;
}
__get_cpu_var(netdev_rx_stat).cpu_collision++;
goto requeue;
@@ -135,10 +132,12 @@ static inline int qdisc_restart(struct net_device *dev)
netif_tx_unlock(dev);
}
spin_lock(&dev->queue_lock);
- return -1;
+ q = dev->qdisc;
+ goto out;
}
if (ret == NETDEV_TX_LOCKED && nolock) {
spin_lock(&dev->queue_lock);
+ q = dev->qdisc;
goto collision;
}
}
@@ -163,26 +162,28 @@ static inline int qdisc_restart(struct net_device *dev)
*/
requeue:
- if (skb->next)
+ if (unlikely(q == &noop_qdisc))
+ kfree_skb(skb);
+ else if (skb->next)
dev->gso_skb = skb;
else
q->ops->requeue(skb, q);
netif_schedule(dev);
- return 1;
+ return 0;
}
+
+out:
BUG_ON((int) q->q.qlen < 0);
return q->q.qlen;
}
void __qdisc_run(struct net_device *dev)
{
- if (unlikely(dev->qdisc == &noop_qdisc))
- goto out;
-
- while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
- /* NOTHING */;
+ do {
+ if (!qdisc_restart(dev))
+ break;
+ } while (!netif_queue_stopped(dev));
-out:
clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
}
@@ -544,6 +545,7 @@ void dev_activate(struct net_device *dev)
void dev_deactivate(struct net_device *dev)
{
struct Qdisc *qdisc;
+ struct sk_buff *skb;
spin_lock_bh(&dev->queue_lock);
qdisc = dev->qdisc;
@@ -551,8 +553,12 @@ void dev_deactivate(struct net_device *dev)
qdisc_reset(qdisc);
+ skb = dev->gso_skb;
+ dev->gso_skb = NULL;
spin_unlock_bh(&dev->queue_lock);
+ kfree_skb(skb);
+
dev_watchdog_down(dev);
/* Wait for outstanding dev_queue_xmit calls. */
@@ -561,11 +567,6 @@ void dev_deactivate(struct net_device *dev)
/* Wait for outstanding qdisc_run calls. */
while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
yield();
-
- if (dev->gso_skb) {
- kfree_skb(dev->gso_skb);
- dev->gso_skb = NULL;
- }
}
void dev_init_scheduler(struct net_device *dev)
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index d24914db786..f05ad9a30b4 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -94,14 +94,13 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch)
struct net_device *dev = sch->dev;
struct teql_sched_data *q = qdisc_priv(sch);
- __skb_queue_tail(&q->q, skb);
- if (q->q.qlen <= dev->tx_queue_len) {
+ if (q->q.qlen < dev->tx_queue_len) {
+ __skb_queue_tail(&q->q, skb);
sch->bstats.bytes += skb->len;
sch->bstats.packets++;
return 0;
}
- __skb_unlink(skb, &q->q);
kfree_skb(skb);
sch->qstats.drops++;
return NET_XMIT_DROP;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 83a76ba9d7b..4dcdabf5647 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4164,6 +4164,7 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
rwlock_t *addr_lock;
int err = 0;
void *addrs;
+ void *buf;
int bytes_copied = 0;
if (len != sizeof(struct sctp_getaddrs_old))
@@ -4217,13 +4218,14 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
}
}
+ buf = addrs;
list_for_each(pos, &bp->address_list) {
addr = list_entry(pos, struct sctp_sockaddr_entry, list);
memcpy(&temp, &addr->a, sizeof(temp));
sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
- memcpy(addrs, &temp, addrlen);
- to += addrlen;
+ memcpy(buf, &temp, addrlen);
+ buf += addrlen;
bytes_copied += addrlen;
cnt ++;
if (cnt >= getaddrs.addr_num) break;
@@ -4266,6 +4268,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
size_t space_left;
int bytes_copied = 0;
void *addrs;
+ void *buf;
if (len <= sizeof(struct sctp_getaddrs))
return -EINVAL;
@@ -4316,6 +4319,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
}
}
+ buf = addrs;
list_for_each(pos, &bp->address_list) {
addr = list_entry(pos, struct sctp_sockaddr_entry, list);
memcpy(&temp, &addr->a, sizeof(temp));
@@ -4325,8 +4329,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
err = -ENOMEM; /*fixme: right error?*/
goto error;
}
- memcpy(addrs, &temp, addrlen);
- to += addrlen;
+ memcpy(buf, &temp, addrlen);
+ buf += addrlen;
bytes_copied += addrlen;
cnt ++;
space_left -= addrlen;
@@ -5227,7 +5231,12 @@ int sctp_inet_listen(struct socket *sock, int backlog)
/* Allocate HMAC for generating cookie. */
if (sctp_hmac_alg) {
tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
- if (!tfm) {
+ if (IS_ERR(tfm)) {
+ if (net_ratelimit()) {
+ printk(KERN_INFO
+ "SCTP: failed to load transform for %s: %ld\n",
+ sctp_hmac_alg, PTR_ERR(tfm));
+ }
err = -ENOSYS;
goto out;
}
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index 661ea2dd78b..bfecb353ab3 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -141,11 +141,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
* an ABORT, so we need to include it in the sac_info.
*/
if (chunk) {
- /* sctp_inqu_pop() has allready pulled off the chunk
- * header. We need to put it back temporarily
- */
- skb_push(chunk->skb, sizeof(sctp_chunkhdr_t));
-
/* Copy the chunk data to a new skb and reserve enough
* head room to use as notification.
*/
@@ -155,9 +150,6 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
if (!skb)
goto fail;
- /* put back the chunk header now that we have a copy */
- skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
-
/* Embed the event fields inside the cloned skb. */
event = sctp_skb2event(skb);
sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
@@ -168,7 +160,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change(
/* Trim the buffer to the right length. */
skb_trim(skb, sizeof(struct sctp_assoc_change) +
- ntohs(chunk->chunk_hdr->length));
+ ntohs(chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t));
} else {
event = sctp_ulpevent_new(sizeof(struct sctp_assoc_change),
MSG_NOTIFICATION, gfp);
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
index e91f9f66f39..ded51671794 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -1018,7 +1018,7 @@ static int onyx_create(struct i2c_adapter *adapter,
onyx->i2c.driver = &onyx_driver;
onyx->i2c.adapter = adapter;
onyx->i2c.addr = addr & 0x7f;
- strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1);
+ strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE);
if (i2c_attach_client(&onyx->i2c)) {
printk(KERN_ERR PFX "failed to attach to i2c\n");
@@ -1033,7 +1033,7 @@ static int onyx_create(struct i2c_adapter *adapter,
goto fail;
}
- strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1);
+ strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
onyx->codec.owner = THIS_MODULE;
onyx->codec.init = onyx_init_codec;
onyx->codec.exit = onyx_exit_codec;
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index 041fe52cbf2..2f771f57c76 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -899,14 +899,14 @@ static int tas_create(struct i2c_adapter *adapter,
tas->i2c.addr = addr;
/* seems that half is a saner default */
tas->drc_range = TAS3004_DRC_MAX / 2;
- strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
+ strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE);
if (i2c_attach_client(&tas->i2c)) {
printk(KERN_ERR PFX "failed to attach to i2c\n");
goto fail;
}
- strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1);
+ strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
tas->codec.owner = THIS_MODULE;
tas->codec.init = tas_init_codec;
tas->codec.exit = tas_exit_codec;
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index 8b2e9b905cd..64d16391433 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -163,8 +163,6 @@ static int soundbus_device_resume(struct device * dev)
#endif /* CONFIG_PM */
-extern struct device_attribute soundbus_dev_attrs[];
-
static struct bus_type soundbus_bus_type = {
.name = "aoa-soundbus",
.probe = soundbus_probe,
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
index 0fccdbf5166..efb9441b3ac 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
@@ -23,9 +23,6 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_DESCRIPTION("Apple Soundbus: I2S support");
-/* for auto-loading, declare that we handle this weird
- * string that macio puts into the relevant device */
-MODULE_ALIAS("of:Ni2sTi2sC");
static int force;
module_param(force, int, 0444);
@@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[] = {
{ }
};
+MODULE_DEVICE_TABLE(of, i2sbus_match);
+
static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
struct dbdma_command_mem *r,
int numcmds)
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h
index 5c27297835d..622cd37a011 100644
--- a/sound/aoa/soundbus/soundbus.h
+++ b/sound/aoa/soundbus/soundbus.h
@@ -199,4 +199,6 @@ struct soundbus_driver {
extern int soundbus_register_driver(struct soundbus_driver *drv);
extern void soundbus_unregister_driver(struct soundbus_driver *drv);
+extern struct device_attribute soundbus_dev_attrs[];
+
#endif /* __SOUNDBUS_H */
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 905234817c8..a96733a5beb 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -712,26 +712,23 @@ static int snd_pcm_action_group(struct action_ops *ops,
struct snd_pcm_substream *substream,
int state, int do_lock)
{
- struct list_head *pos;
struct snd_pcm_substream *s = NULL;
struct snd_pcm_substream *s1;
int res = 0;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (do_lock && s != substream)
- spin_lock(&s->self_group.lock);
+ spin_lock_nested(&s->self_group.lock,
+ SINGLE_DEPTH_NESTING);
res = ops->pre_action(s, state);
if (res < 0)
goto _unlock;
}
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
res = ops->do_action(s, state);
if (res < 0) {
if (ops->undo_action) {
- snd_pcm_group_for_each(pos, substream) {
- s1 = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s1, substream) {
if (s1 == s) /* failed stream */
break;
ops->undo_action(s1, state);
@@ -741,15 +738,13 @@ static int snd_pcm_action_group(struct action_ops *ops,
goto _unlock;
}
}
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
ops->post_action(s, state);
}
_unlock:
if (do_lock) {
/* unlock streams */
- snd_pcm_group_for_each(pos, substream) {
- s1 = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s1, substream) {
if (s1 != substream)
spin_unlock(&s1->self_group.lock);
if (s1 == s) /* end */
@@ -1438,7 +1433,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
{
struct snd_card *card;
struct snd_pcm_runtime *runtime;
- struct list_head *pos;
+ struct snd_pcm_substream *s;
int result = 0;
int i, num_drecs;
struct drain_rec *drec, drec_tmp, *d;
@@ -1473,8 +1468,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
/* count only playback streams */
num_drecs = 0;
- snd_pcm_group_for_each(pos, substream) {
- struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
runtime = s->runtime;
if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
d = &drec[num_drecs++];
@@ -1674,7 +1668,7 @@ static void relink_to_local(struct snd_pcm_substream *substream)
static int snd_pcm_unlink(struct snd_pcm_substream *substream)
{
- struct list_head *pos;
+ struct snd_pcm_substream *s;
int res = 0;
down_write(&snd_pcm_link_rwsem);
@@ -1686,8 +1680,8 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
list_del(&substream->link_list);
substream->group->count--;
if (substream->group->count == 1) { /* detach the last stream, too */
- snd_pcm_group_for_each(pos, substream) {
- relink_to_local(snd_pcm_group_substream_entry(pos));
+ snd_pcm_group_for_each_entry(s, substream) {
+ relink_to_local(s);
break;
}
kfree(substream->group);
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 9f7b32e1ccd..7cd5e8f5d4c 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
+#include <linux/log2.h>
#include <sound/core.h>
#include <sound/timer.h>
@@ -129,7 +130,7 @@ static int __init rtctimer_init(void)
struct snd_timer *timer;
if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
- (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
+ !is_power_of_2(rtctimer_freq)) {
snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
rtctimer_freq);
return -EINVAL;
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 2de181ad0b0..1d563e515c1 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -42,6 +42,7 @@ static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
#endif
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
+static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
@@ -57,6 +58,8 @@ module_param_array(port, long, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
module_param_array(irq, int, NULL, 0444);
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
+module_param_array(uart_enter, bool, NULL, 0444);
+MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open.");
static struct platform_device *platform_devices[SNDRV_CARDS];
static int pnp_registered;
@@ -80,10 +83,11 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
strcat(card->longname, "polled");
}
- if ((err = snd_mpu401_uart_new(card, 0,
- MPU401_HW_MPU401,
- port[dev], 0,
- irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev],
+ uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY,
+ irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0,
+ NULL);
+ if (err < 0) {
printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
goto _err;
}
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 3daa9fa56c0..85aedc348e2 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -266,6 +266,16 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
return 0;
}
+static int snd_mpu401_do_reset(struct snd_mpu401 *mpu)
+{
+ if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
+ return -EIO;
+ if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) &&
+ snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+ return -EIO;
+ return 0;
+}
+
/*
* input/output open/close - protected by open_mutex in rawmidi.c
*/
@@ -278,9 +288,7 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
return err;
if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
- if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
- goto error_out;
- if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+ if (snd_mpu401_do_reset(mpu) < 0)
goto error_out;
}
mpu->substream_input = substream;
@@ -302,9 +310,7 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
return err;
if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
- if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
- goto error_out;
- if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+ if (snd_mpu401_do_reset(mpu) < 0)
goto error_out;
}
mpu->substream_output = substream;
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 6c9f4c9bfeb..ebb1bdac723 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -892,13 +892,13 @@ static void __devinit snd_mts64_attach(struct parport *p)
struct platform_device *device;
device = platform_device_alloc(PLATFORM_DRIVER, device_count);
- if (!device)
+ if (!device)
return;
/* Temporary assignment to forward the parport */
platform_set_drvdata(device, p);
- if (platform_device_register(device) < 0) {
+ if (platform_device_add(device) < 0) {
platform_device_put(device);
return;
}
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index b2d0ba4bd18..497cafb57d9 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -676,13 +676,13 @@ static void __devinit snd_portman_attach(struct parport *p)
struct platform_device *device;
device = platform_device_alloc(PLATFORM_DRIVER, device_count);
- if (!device)
+ if (!device)
return;
/* Temporary assignment to forward the parport */
platform_set_drvdata(device, p);
- if (platform_device_register(device) < 0) {
+ if (platform_device_add(device) < 0) {
platform_device_put(device);
return;
}
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index e1920af4501..9a8154c9416 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -30,6 +30,20 @@
#ifdef SND_VX_FW_LOADER
+MODULE_FIRMWARE("vx/bx_1_vxp.b56");
+MODULE_FIRMWARE("vx/bx_1_vp4.b56");
+MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
+MODULE_FIRMWARE("vx/x1_2_v22.xlx");
+MODULE_FIRMWARE("vx/x1_1_vxp.xlx");
+MODULE_FIRMWARE("vx/x1_1_vp4.xlx");
+MODULE_FIRMWARE("vx/bd56002.boot");
+MODULE_FIRMWARE("vx/bd563v2.boot");
+MODULE_FIRMWARE("vx/bd563s3.boot");
+MODULE_FIRMWARE("vx/l_1_vx2.d56");
+MODULE_FIRMWARE("vx/l_1_v22.d56");
+MODULE_FIRMWARE("vx/l_1_vxp.d56");
+MODULE_FIRMWARE("vx/l_1_vp4.d56");
+
int snd_vx_setup_firmware(struct vx_core *chip)
{
static char *fw_files[VX_TYPE_NUMS][4] = {
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index adbfd5884d0..1efb973137a 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
#define AK4114_ADDR 0x00 /* fixed address */
static void ak4114_stats(struct work_struct *work);
+static void ak4114_init_regs(struct ak4114 *chip);
static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val)
{
@@ -105,7 +106,7 @@ int snd_ak4114_create(struct snd_card *card,
for (reg = 0; reg < 5; reg++)
chip->txcsb[reg] = txcsb[reg];
- snd_ak4114_reinit(chip);
+ ak4114_init_regs(chip);
chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);
@@ -131,13 +132,10 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char
(chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val);
}
-void snd_ak4114_reinit(struct ak4114 *chip)
+static void ak4114_init_regs(struct ak4114 *chip)
{
unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg;
- chip->init = 1;
- mb();
- flush_scheduled_work();
/* bring the chip to reset state and powerdown state */
reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN));
udelay(200);
@@ -150,9 +148,18 @@ void snd_ak4114_reinit(struct ak4114 *chip)
reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]);
/* release powerdown, everything is initialized now */
reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN);
+}
+
+void snd_ak4114_reinit(struct ak4114 *chip)
+{
+ chip->init = 1;
+ mb();
+ flush_scheduled_work();
+ ak4114_init_regs(chip);
/* bring up statistics / event queing */
chip->init = 0;
- schedule_delayed_work(&chip->work, HZ / 10);
+ if (chip->kctls[0])
+ schedule_delayed_work(&chip->work, HZ / 10);
}
static unsigned int external_rate(unsigned char rcs1)
@@ -428,7 +435,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = snd_ak4114_in_bit_info,
.get = snd_ak4114_in_bit_get,
- .private_value = (6<<8) | AK4114_REG_RCS1,
+ .private_value = (6<<8) | AK4114_REG_RCS0,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -436,7 +443,15 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = snd_ak4114_in_bit_info,
.get = snd_ak4114_in_bit_get,
- .private_value = (3<<8) | AK4114_REG_RCS1,
+ .private_value = (3<<8) | AK4114_REG_RCS0,
+},
+{
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "IEC958 PPL Lock Status",
+ .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .info = snd_ak4114_in_bit_info,
+ .get = snd_ak4114_in_bit_get,
+ .private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0,
}
};
@@ -455,7 +470,7 @@ int snd_ak4114_build(struct ak4114 *ak4114,
kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114);
if (kctl == NULL)
return -ENOMEM;
- if (!strstr(kctl->id.name, "Playback")) {
+ if (strstr(kctl->id.name, "Playback")) {
if (ply_substream == NULL) {
snd_ctl_free_one(kctl);
ak4114->kctls[idx] = NULL;
@@ -472,9 +487,58 @@ int snd_ak4114_build(struct ak4114 *ak4114,
return err;
ak4114->kctls[idx] = kctl;
}
+ /* trigger workq */
+ schedule_delayed_work(&ak4114->work, HZ / 10);
return 0;
}
+/* notify kcontrols if any parameters are changed */
+static void ak4114_notify(struct ak4114 *ak4114,
+ unsigned char rcs0, unsigned char rcs1,
+ unsigned char c0, unsigned char c1)
+{
+ if (!ak4114->kctls[0])
+ return;
+
+ if (rcs0 & AK4114_PAR)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[0]->id);
+ if (rcs0 & AK4114_V)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[1]->id);
+ if (rcs1 & AK4114_CCRC)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[2]->id);
+ if (rcs1 & AK4114_QCRC)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[3]->id);
+
+ /* rate change */
+ if (c1 & 0xf0)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[4]->id);
+
+ if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[9]->id);
+ if (c0 & AK4114_QINT)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[10]->id);
+
+ if (c0 & AK4114_AUDION)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[11]->id);
+ if (c0 & AK4114_AUTO)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[12]->id);
+ if (c0 & AK4114_DTSCD)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[13]->id);
+ if (c0 & AK4114_UNLCK)
+ snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &ak4114->kctls[14]->id);
+}
+
int snd_ak4114_external_rate(struct ak4114 *ak4114)
{
unsigned char rcs1;
@@ -511,31 +575,7 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
ak4114->rcs1 = rcs1;
spin_unlock_irqrestore(&ak4114->lock, _flags);
- if (rcs0 & AK4114_PAR)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id);
- if (rcs0 & AK4114_V)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id);
- if (rcs1 & AK4114_CCRC)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id);
- if (rcs1 & AK4114_QCRC)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id);
-
- /* rate change */
- if (c1 & 0xf0)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id);
-
- if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id);
- if (c0 & AK4114_QINT)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id);
-
- if (c0 & AK4114_AUDION)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id);
- if (c0 & AK4114_AUTO)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id);
- if (c0 & AK4114_DTSCD)
- snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id);
-
+ ak4114_notify(ak4114, rcs0, rcs1, c0, c1);
if (ak4114->change_callback && (c0 | c1) != 0)
ak4114->change_callback(ak4114, c0, c1);
@@ -558,9 +598,9 @@ static void ak4114_stats(struct work_struct *work)
{
struct ak4114 *chip = container_of(work, struct ak4114, work.work);
- if (chip->init)
- return;
- snd_ak4114_check_rate_and_errors(chip, 0);
+ if (!chip->init)
+ snd_ak4114_check_rate_and_errors(chip, 0);
+
schedule_delayed_work(&chip->work, HZ / 10);
}
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 4e3a9729f56..cf3803cd579 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -358,12 +358,21 @@ config SND_SBAWE
config SND_SB16_CSP
bool "Sound Blaster 16/AWE CSP support"
depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
- select FW_LOADER
+ select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL
help
Say Y here to include support for the CSP core. This special
coprocessor can do variable tasks like various compression and
decompression algorithms.
+config SND_SB16_CSP_FIRMWARE_IN_KERNEL
+ bool "In-kernel firmware for SB16 CSP"
+ depends on SND_SB16_CSP
+ default y
+ help
+ Say Y here to include the static firmware built in the kernel
+ for the SB16 CSP controller. If you choose N here, you need
+ to install the firmware files from the alsa-firmware package.
+
config SND_SGALAXY
tristate "Aztech Sound Galaxy"
depends on SND
@@ -391,7 +400,7 @@ config SND_SSCAPE
config SND_WAVEFRONT
tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
depends on SND
- select FW_LOADER
+ select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_CS4231_LIB
@@ -402,4 +411,13 @@ config SND_WAVEFRONT
To compile this driver as a module, choose M here: the module
will be called snd-wavefront.
+config SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+ bool "In-kernel firmware for Wavefront"
+ depends on SND_WAVEFRONT
+ default y
+ help
+ Say Y here to include the static firmware built in the kernel
+ for the Wavefront driver. If you choose N here, you need to
+ install the firmware files from the alsa-firmware package.
+
endmenu
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 59034507175..fc88a31da6f 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -129,8 +129,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
}
acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
if (acard->devmpu == NULL) {
- kfree(cfg);
- return -EBUSY;
+ mpu_port[dev] = -1;
+ snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
}
pdev = acard->dev;
@@ -162,6 +162,10 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
dma2[dev] = pnp_dma(pdev, 1);
irq[dev] = pnp_irq(pdev, 0);
+ if (acard->devmpu == NULL) {
+ kfree(cfg);
+ return 0;
+ }
pdev = acard->devmpu;
pnp_init_resource_table(cfg);
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 74e501dea8b..d09a7fa8654 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -24,7 +24,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/moduleparam.h>
@@ -32,8 +32,11 @@
#include <sound/ad1848.h>
#include <sound/initval.h>
+#define CRD_NAME "Generic AD1848/AD1847/CS4248"
+#define DEV_NAME "ad1848"
+
+MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("AD1848/AD1847/CS4248");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848},"
"{Analog Devices,AD1847},"
@@ -48,95 +51,98 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */
module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for AD1848 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for AD1848 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable AD1848 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for AD1848 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for AD1848 driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
module_param_array(thinkpad, bool, NULL, 0444);
MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
+{
+ if (!enable[n])
+ return 0;
+ if (port[n] == SNDRV_AUTO_PORT) {
+ snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+ return 0;
+ }
+ if (irq[n] == SNDRV_AUTO_IRQ) {
+ snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
+ return 0;
+ }
+ if (dma1[n] == SNDRV_AUTO_DMA) {
+ snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
+ return 0;
+ }
+ return 1;
+}
-static int __devinit snd_ad1848_probe(struct platform_device *pdev)
+static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
{
- int dev = pdev->id;
struct snd_card *card;
struct snd_ad1848 *chip;
struct snd_pcm *pcm;
- int err;
+ int error;
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "ad1848: specify port\n");
+ card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+ if (!card)
return -EINVAL;
- }
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- snd_printk(KERN_ERR "ad1848: specify irq\n");
- return -EINVAL;
- }
- if (dma1[dev] == SNDRV_AUTO_DMA) {
- snd_printk(KERN_ERR "ad1848: specify dma1\n");
- return -EINVAL;
- }
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ error = snd_ad1848_create(card, port[n], irq[n], dma1[n],
+ thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip);
+ if (error < 0)
+ goto out;
- if ((err = snd_ad1848_create(card, port[dev],
- irq[dev],
- dma1[dev],
- thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
- &chip)) < 0)
- goto _err;
card->private_data = chip;
- if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
- goto _err;
+ error = snd_ad1848_pcm(chip, 0, &pcm);
+ if (error < 0)
+ goto out;
- if ((err = snd_ad1848_mixer(chip)) < 0)
- goto _err;
+ error = snd_ad1848_mixer(chip);
+ if (error < 0)
+ goto out;
strcpy(card->driver, "AD1848");
strcpy(card->shortname, pcm->name);
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- pcm->name, chip->port, irq[dev], dma1[dev]);
-
- if (thinkpad[dev])
+ pcm->name, chip->port, irq[n], dma1[n]);
+ if (thinkpad[n])
strcat(card->longname, " [Thinkpad]");
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, dev);
- if ((err = snd_card_register(card)) < 0)
- goto _err;
+ error = snd_card_register(card);
+ if (error < 0)
+ goto out;
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(dev, card);
return 0;
- _err:
- snd_card_free(card);
- return err;
+out: snd_card_free(card);
+ return error;
}
-static int __devexit snd_ad1848_remove(struct platform_device *devptr)
+static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(dev));
+ dev_set_drvdata(dev, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
+static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(dev);
struct snd_ad1848 *chip = card->private_data;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -144,9 +150,9 @@ static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int snd_ad1848_resume(struct platform_device *pdev)
+static int snd_ad1848_resume(struct device *dev, unsigned int n)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(dev);
struct snd_ad1848 *chip = card->private_data;
chip->resume(chip);
@@ -155,9 +161,8 @@ static int snd_ad1848_resume(struct platform_device *pdev)
}
#endif
-#define SND_AD1848_DRIVER "snd_ad1848"
-
-static struct platform_driver snd_ad1848_driver = {
+static struct isa_driver snd_ad1848_driver = {
+ .match = snd_ad1848_match,
.probe = snd_ad1848_probe,
.remove = __devexit_p(snd_ad1848_remove),
#ifdef CONFIG_PM
@@ -165,57 +170,19 @@ static struct platform_driver snd_ad1848_driver = {
.resume = snd_ad1848_resume,
#endif
.driver = {
- .name = SND_AD1848_DRIVER
- },
+ .name = DEV_NAME
+ }
};
-static void __init_or_module snd_ad1848_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_ad1848_driver);
-}
-
static int __init alsa_card_ad1848_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_ad1848_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_AD1848_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "AD1848 soundcard not found or device busy\n");
-#endif
- snd_ad1848_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS);
}
static void __exit alsa_card_ad1848_exit(void)
{
- snd_ad1848_unregister_all();
+ isa_unregister_driver(&snd_ad1848_driver);
}
-module_init(alsa_card_ad1848_init)
-module_exit(alsa_card_ad1848_exit)
+module_init(alsa_card_ad1848_init);
+module_exit(alsa_card_ad1848_exit);
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
index 1124344ed94..d68720724c9 100644
--- a/sound/isa/adlib.c
+++ b/sound/isa/adlib.c
@@ -5,13 +5,13 @@
#include <sound/driver.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/opl3.h>
#define CRD_NAME "AdLib FM"
-#define DRV_NAME "snd_adlib"
+#define DEV_NAME "adlib"
MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Rene Herman");
@@ -31,133 +31,99 @@ MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param_array(port, long, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_adlib_match(struct device *dev, unsigned int n)
+{
+ if (!enable[n])
+ return 0;
+
+ if (port[n] == SNDRV_AUTO_PORT) {
+ snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+ return 0;
+ }
+ return 1;
+}
static void snd_adlib_free(struct snd_card *card)
{
release_and_free_resource(card->private_data);
}
-static int __devinit snd_adlib_probe(struct platform_device *device)
+static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
{
struct snd_card *card;
struct snd_opl3 *opl3;
+ int error;
- int error, i = device->id;
-
- if (port[i] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR DRV_NAME ": please specify port\n");
- error = -EINVAL;
- goto out0;
- }
-
- card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
+ card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
if (!card) {
- snd_printk(KERN_ERR DRV_NAME ": could not create card\n");
- error = -EINVAL;
- goto out0;
+ snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id);
+ return -EINVAL;
}
- card->private_data = request_region(port[i], 4, CRD_NAME);
+ card->private_data = request_region(port[n], 4, CRD_NAME);
if (!card->private_data) {
- snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n");
+ snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id);
error = -EBUSY;
- goto out1;
+ goto out;
}
card->private_free = snd_adlib_free;
- error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3);
+ strcpy(card->driver, DEV_NAME);
+ strcpy(card->shortname, CRD_NAME);
+ sprintf(card->longname, CRD_NAME " at %#lx", port[n]);
+
+ error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
if (error < 0) {
- snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n");
- goto out1;
+ snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id);
+ goto out;
}
error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
if (error < 0) {
- snd_printk(KERN_ERR DRV_NAME ": could not create FM\n");
- goto out1;
+ snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id);
+ goto out;
}
- strcpy(card->driver, DRV_NAME);
- strcpy(card->shortname, CRD_NAME);
- sprintf(card->longname, CRD_NAME " at %#lx", port[i]);
-
- snd_card_set_dev(card, &device->dev);
+ snd_card_set_dev(card, dev);
error = snd_card_register(card);
if (error < 0) {
- snd_printk(KERN_ERR DRV_NAME ": could not register card\n");
- goto out1;
+ snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id);
+ goto out;
}
- platform_set_drvdata(device, card);
+ dev_set_drvdata(dev, card);
return 0;
-out1: snd_card_free(card);
-out0: return error;
+out: snd_card_free(card);
+ return error;
}
-static int __devexit snd_adlib_remove(struct platform_device *device)
+static int __devexit snd_adlib_remove(struct device *dev, unsigned int n)
{
- snd_card_free(platform_get_drvdata(device));
- platform_set_drvdata(device, NULL);
+ snd_card_free(dev_get_drvdata(dev));
+ dev_set_drvdata(dev, NULL);
return 0;
}
-static struct platform_driver snd_adlib_driver = {
+static struct isa_driver snd_adlib_driver = {
+ .match = snd_adlib_match,
.probe = snd_adlib_probe,
.remove = __devexit_p(snd_adlib_remove),
.driver = {
- .name = DRV_NAME
+ .name = DEV_NAME
}
};
static int __init alsa_card_adlib_init(void)
{
- int i, cards;
-
- if (platform_driver_register(&snd_adlib_driver) < 0) {
- snd_printk(KERN_ERR DRV_NAME ": could not register driver\n");
- return -ENODEV;
- }
-
- for (cards = 0, i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
-
- if (!enable[i])
- continue;
-
- device = platform_device_register_simple(DRV_NAME, i, NULL, 0);
- if (IS_ERR(device))
- continue;
-
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
-
- devices[i] = device;
- cards++;
- }
-
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n");
-#endif
- platform_driver_unregister(&snd_adlib_driver);
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS);
}
static void __exit alsa_card_adlib_exit(void)
{
- int i;
-
- for (i = 0; i < SNDRV_CARDS; i++)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_adlib_driver);
+ isa_unregister_driver(&snd_adlib_driver);
}
module_init(alsa_card_adlib_init);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index c09a8009d2f..214d65d94c4 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -46,7 +46,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
@@ -108,7 +108,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver.");
module_param_array(wssdma, int, NULL, 0444);
MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
-static struct platform_device *platform_devices[SNDRV_CARDS];
#ifdef CONFIG_PNP
static int pnp_registered;
#endif
@@ -547,70 +546,78 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
return snd_card_register(card);
}
-static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_cmi8330_isa_match(struct device *pdev,
+ unsigned int dev)
{
- struct snd_card *card;
- int err;
- int dev = pdev->id;
-
+ if (!enable[dev] || is_isapnp_selected(dev))
+ return 0;
if (wssport[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify wssport\n");
- return -EINVAL;
+ return 0;
}
if (sbport[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify sbport\n");
- return -EINVAL;
+ return 0;
}
+ return 1;
+}
+
+static int __devinit snd_cmi8330_isa_probe(struct device *pdev,
+ unsigned int dev)
+{
+ struct snd_card *card;
+ int err;
card = snd_cmi8330_card_new(dev);
if (! card)
return -ENOMEM;
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, pdev);
if ((err = snd_cmi8330_probe(card, dev)) < 0) {
snd_card_free(card);
return err;
}
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(pdev, card);
return 0;
}
-static int __devexit snd_cmi8330_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_cmi8330_isa_remove(struct device *devptr,
+ unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n,
+ pm_message_t state)
{
- return snd_cmi8330_suspend(platform_get_drvdata(dev));
+ return snd_cmi8330_suspend(dev_get_drvdata(dev));
}
-static int snd_cmi8330_nonpnp_resume(struct platform_device *dev)
+static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n)
{
- return snd_cmi8330_resume(platform_get_drvdata(dev));
+ return snd_cmi8330_resume(dev_get_drvdata(dev));
}
#endif
-#define CMI8330_DRIVER "snd_cmi8330"
+#define DEV_NAME "cmi8330"
-static struct platform_driver snd_cmi8330_driver = {
- .probe = snd_cmi8330_nonpnp_probe,
- .remove = __devexit_p(snd_cmi8330_nonpnp_remove),
+static struct isa_driver snd_cmi8330_driver = {
+ .match = snd_cmi8330_isa_match,
+ .probe = snd_cmi8330_isa_probe,
+ .remove = __devexit_p(snd_cmi8330_isa_remove),
#ifdef CONFIG_PM
- .suspend = snd_cmi8330_nonpnp_suspend,
- .resume = snd_cmi8330_nonpnp_resume,
+ .suspend = snd_cmi8330_isa_suspend,
+ .resume = snd_cmi8330_isa_resume,
#endif
.driver = {
- .name = CMI8330_DRIVER
+ .name = DEV_NAME
},
};
#ifdef CONFIG_PNP
-static unsigned int __devinitdata cmi8330_pnp_devices;
-
static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
@@ -640,7 +647,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
}
pnp_set_card_drvdata(pcard, card);
dev++;
- cmi8330_pnp_devices++;
return 0;
}
@@ -675,63 +681,28 @@ static struct pnp_card_driver cmi8330_pnpc_driver = {
};
#endif /* CONFIG_PNP */
-static void __init_or_module snd_cmi8330_unregister_all(void)
-{
- int i;
-
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-#endif
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_cmi8330_driver);
-}
-
static int __init alsa_card_cmi8330_init(void)
{
- int i, err, cards = 0;
+ int err;
- if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0)
+ err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
+ if (err < 0)
return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i] || is_isapnp_selected(i))
- continue;
- device = platform_device_register_simple(CMI8330_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- cards++;
- }
-
#ifdef CONFIG_PNP
err = pnp_register_card_driver(&cmi8330_pnpc_driver);
- if (!err) {
+ if (!err)
pnp_registered = 1;
- cards += cmi8330_pnp_devices;
- }
#endif
-
- if (!cards) {
-#ifdef MODULE
- snd_printk(KERN_ERR "CMI8330 not found or device busy\n");
-#endif
- snd_cmi8330_unregister_all();
- return -ENODEV;
- }
return 0;
}
static void __exit alsa_card_cmi8330_exit(void)
{
- snd_cmi8330_unregister_all();
+#ifdef CONFIG_PNP
+ if (pnp_registered)
+ pnp_unregister_card_driver(&cmi8330_pnpc_driver);
+#endif
+ isa_unregister_driver(&snd_cmi8330_driver);
}
module_init(alsa_card_cmi8330_init)
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index 696a5c86bcf..ac404113415 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -23,7 +23,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/moduleparam.h>
@@ -32,8 +32,11 @@
#include <sound/mpu401.h>
#include <sound/initval.h>
+#define CRD_NAME "Generic CS4231"
+#define DEV_NAME "cs4231"
+
+MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Generic CS4231");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}");
@@ -48,132 +51,136 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */
module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for CS4231 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for CS4231 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable CS4231 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for CS4231 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for CS4231 driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for CS4231 driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for CS4231 driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver.");
+MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
+{
+ if (!enable[n])
+ return 0;
+ if (port[n] == SNDRV_AUTO_PORT) {
+ snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+ return 0;
+ }
+ if (irq[n] == SNDRV_AUTO_IRQ) {
+ snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
+ return 0;
+ }
+ if (dma1[n] == SNDRV_AUTO_DMA) {
+ snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
+ return 0;
+ }
+ return 1;
+}
-static int __init snd_cs4231_probe(struct platform_device *pdev)
+static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
{
- int dev = pdev->id;
struct snd_card *card;
- struct snd_pcm *pcm;
struct snd_cs4231 *chip;
- int err;
+ struct snd_pcm *pcm;
+ int error;
- if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify port\n");
- return -EINVAL;
- }
- if (irq[dev] == SNDRV_AUTO_IRQ) {
- snd_printk(KERN_ERR "specify irq\n");
- return -EINVAL;
- }
- if (dma1[dev] == SNDRV_AUTO_DMA) {
- snd_printk(KERN_ERR "specify dma1\n");
+ card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+ if (!card)
return -EINVAL;
- }
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
- if ((err = snd_cs4231_create(card, port[dev], -1,
- irq[dev],
- dma1[dev],
- dma2[dev],
- CS4231_HW_DETECT,
- 0, &chip)) < 0)
- goto _err;
+
+ error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n],
+ CS4231_HW_DETECT, 0, &chip);
+ if (error < 0)
+ goto out;
+
card->private_data = chip;
- if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
- goto _err;
+ error = snd_cs4231_pcm(chip, 0, &pcm);
+ if (error < 0)
+ goto out;
strcpy(card->driver, "CS4231");
strcpy(card->shortname, pcm->name);
+
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- pcm->name, chip->port, irq[dev], dma1[dev]);
- if (dma2[dev] >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
-
- if ((err = snd_cs4231_mixer(chip)) < 0)
- goto _err;
- if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
- goto _err;
-
- if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
- if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
- mpu_irq[dev] = -1;
+ pcm->name, chip->port, irq[n], dma1[n]);
+ if (dma2[n] >= 0)
+ sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
+
+ error = snd_cs4231_mixer(chip);
+ if (error < 0)
+ goto out;
+
+ error = snd_cs4231_timer(chip, 0, NULL);
+ if (error < 0)
+ goto out;
+
+ if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) {
+ if (mpu_irq[n] == SNDRV_AUTO_IRQ)
+ mpu_irq[n] = -1;
if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
- mpu_port[dev], 0,
- mpu_irq[dev],
- mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
+ mpu_port[n], 0, mpu_irq[n],
+ mpu_irq[n] >= 0 ? IRQF_DISABLED : 0,
NULL) < 0)
- printk(KERN_WARNING "cs4231: MPU401 not detected\n");
+ printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id);
}
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, dev);
- if ((err = snd_card_register(card)) < 0)
- goto _err;
+ error = snd_card_register(card);
+ if (error < 0)
+ goto out;
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(dev, card);
return 0;
- _err:
- snd_card_free(card);
- return err;
+out: snd_card_free(card);
+ return error;
}
-static int __devexit snd_cs4231_remove(struct platform_device *devptr)
+static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(dev));
+ dev_set_drvdata(dev, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state)
{
- struct snd_card *card;
- struct snd_cs4231 *chip;
- card = platform_get_drvdata(dev);
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct snd_cs4231 *chip = card->private_data;
+
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- chip = card->private_data;
chip->suspend(chip);
return 0;
}
-static int snd_cs4231_resume(struct platform_device *dev)
+static int snd_cs4231_resume(struct device *dev, unsigned int n)
{
- struct snd_card *card;
- struct snd_cs4231 *chip;
- card = platform_get_drvdata(dev);
- chip = card->private_data;
+ struct snd_card *card = dev_get_drvdata(dev);
+ struct snd_cs4231 *chip = card->private_data;
+
chip->resume(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
#endif
-#define SND_CS4231_DRIVER "snd_cs4231"
-
-static struct platform_driver snd_cs4231_driver = {
+static struct isa_driver snd_cs4231_driver = {
+ .match = snd_cs4231_match,
.probe = snd_cs4231_probe,
.remove = __devexit_p(snd_cs4231_remove),
#ifdef CONFIG_PM
@@ -181,57 +188,19 @@ static struct platform_driver snd_cs4231_driver = {
.resume = snd_cs4231_resume,
#endif
.driver = {
- .name = SND_CS4231_DRIVER
- },
+ .name = DEV_NAME
+ }
};
-static void __init_or_module snd_cs4231_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_cs4231_driver);
-}
-
static int __init alsa_card_cs4231_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_cs4231_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_CS4231_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "CS4231 soundcard not found or device busy\n");
-#endif
- snd_cs4231_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS);
}
static void __exit alsa_card_cs4231_exit(void)
{
- snd_cs4231_unregister_all();
+ isa_unregister_driver(&snd_cs4231_driver);
}
-module_init(alsa_card_cs4231_init)
-module_exit(alsa_card_cs4231_exit)
+module_init(alsa_card_cs4231_init);
+module_exit(alsa_card_cs4231_exit);
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 75c7c5f0198..914d77b61b0 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -405,7 +405,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
int result = 0;
unsigned int what;
- struct list_head *pos;
struct snd_pcm_substream *s;
int do_start;
@@ -425,8 +424,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
}
what = 0;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == chip->playback_substream) {
what |= CS4231_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 07ffd5c22e8..87f1392a2fa 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -22,7 +22,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
@@ -75,10 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235},"
#ifdef CS4232
#define IDENT "CS4232"
-#define CS423X_DRIVER "snd_cs4232"
+#define DEV_NAME "cs4232"
#else
#define IDENT "CS4236+"
-#define CS423X_DRIVER "snd_cs4236"
+#define DEV_NAME "cs4236"
#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
@@ -126,14 +126,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
module_param_array(dma2, int, NULL, 0444);
MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
-static struct platform_device *platform_devices[SNDRV_CARDS];
#ifdef CONFIG_PNP
static int pnpc_registered;
#ifdef CS4232
static int pnp_registered;
#endif
#endif /* CONFIG_PNP */
-static unsigned int snd_cs423x_devices;
struct snd_card_cs4236 {
struct snd_cs4231 *chip;
@@ -542,38 +540,55 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
return snd_card_register(card);
}
-static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_cs423x_isa_match(struct device *pdev,
+ unsigned int dev)
{
- int dev = pdev->id;
- struct snd_card *card;
- int err;
+ if (!enable[dev] || is_isapnp_selected(dev))
+ return 0;
if (port[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify port\n");
- return -EINVAL;
+ snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id);
+ return 0;
}
if (cport[dev] == SNDRV_AUTO_PORT) {
- snd_printk(KERN_ERR "specify cport\n");
- return -EINVAL;
+ snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id);
+ return 0;
+ }
+ if (irq[dev] == SNDRV_AUTO_IRQ) {
+ snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
+ return 0;
}
+ if (dma1[dev] == SNDRV_AUTO_DMA) {
+ snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id);
+ return 0;
+ }
+ return 1;
+}
+
+static int __devinit snd_cs423x_isa_probe(struct device *pdev,
+ unsigned int dev)
+{
+ struct snd_card *card;
+ int err;
card = snd_cs423x_card_new(dev);
if (! card)
return -ENOMEM;
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, pdev);
if ((err = snd_cs423x_probe(card, dev)) < 0) {
snd_card_free(card);
return err;
}
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(pdev, card);
return 0;
}
-static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_cs423x_isa_remove(struct device *pdev,
+ unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(pdev));
+ dev_set_drvdata(pdev, NULL);
return 0;
}
@@ -594,26 +609,28 @@ static int snd_cs423x_resume(struct snd_card *card)
return 0;
}
-static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n,
+ pm_message_t state)
{
- return snd_cs423x_suspend(platform_get_drvdata(dev));
+ return snd_cs423x_suspend(dev_get_drvdata(dev));
}
-static int snd_cs423x_nonpnp_resume(struct platform_device *dev)
+static int snd_cs423x_isa_resume(struct device *dev, unsigned int n)
{
- return snd_cs423x_resume(platform_get_drvdata(dev));
+ return snd_cs423x_resume(dev_get_drvdata(dev));
}
#endif
-static struct platform_driver cs423x_nonpnp_driver = {
- .probe = snd_cs423x_nonpnp_probe,
- .remove = __devexit_p(snd_cs423x_nonpnp_remove),
+static struct isa_driver cs423x_isa_driver = {
+ .match = snd_cs423x_isa_match,
+ .probe = snd_cs423x_isa_probe,
+ .remove = __devexit_p(snd_cs423x_isa_remove),
#ifdef CONFIG_PM
- .suspend = snd_cs423x_nonpnp_suspend,
- .resume = snd_cs423x_nonpnp_resume,
+ .suspend = snd_cs423x_isa_suspend,
+ .resume = snd_cs423x_isa_resume,
#endif
.driver = {
- .name = CS423X_DRIVER
+ .name = DEV_NAME
},
};
@@ -651,7 +668,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
}
pnp_set_drvdata(pdev, card);
dev++;
- snd_cs423x_devices++;
return 0;
}
@@ -715,7 +731,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
}
pnp_set_card_drvdata(pcard, card);
dev++;
- snd_cs423x_devices++;
return 0;
}
@@ -750,45 +765,13 @@ static struct pnp_card_driver cs423x_pnpc_driver = {
};
#endif /* CONFIG_PNP */
-static void __init_or_module snd_cs423x_unregister_all(void)
-{
- int i;
-
-#ifdef CONFIG_PNP
- if (pnpc_registered)
- pnp_unregister_card_driver(&cs423x_pnpc_driver);
-#ifdef CS4232
- if (pnp_registered)
- pnp_unregister_driver(&cs4232_pnp_driver);
-#endif
-#endif /* CONFIG_PNP */
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&cs423x_nonpnp_driver);
-}
-
static int __init alsa_card_cs423x_init(void)
{
- int i, err;
+ int err;
- if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
+ err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
+ if (err < 0)
return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i] || is_isapnp_selected(i))
- continue;
- device = platform_device_register_simple(CS423X_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- snd_cs423x_devices++;
- }
#ifdef CONFIG_PNP
#ifdef CS4232
err = pnp_register_driver(&cs4232_pnp_driver);
@@ -799,20 +782,20 @@ static int __init alsa_card_cs423x_init(void)
if (!err)
pnpc_registered = 1;
#endif /* CONFIG_PNP */
-
- if (!snd_cs423x_devices) {
-#ifdef MODULE
- printk(KERN_ERR IDENT " soundcard not found or device busy\n");
-#endif
- snd_cs423x_unregister_all();
- return -ENODEV;
- }
return 0;
}
static void __exit alsa_card_cs423x_exit(void)
{
- snd_cs423x_unregister_all();
+#ifdef CONFIG_PNP
+ if (pnpc_registered)
+ pnp_unregister_card_driver(&cs423x_pnpc_driver);
+#ifdef CS4232
+ if (pnp_registered)
+ pnp_unregister_driver(&cs4232_pnp_driver);
+#endif
+#endif /* CONFIG_PNP */
+ isa_unregister_driver(&cs423x_isa_driver);
}
module_init(alsa_card_cs423x_init)
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 65f97ff4eef..edc398712e8 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -22,7 +22,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/moduleparam.h>
@@ -35,8 +35,11 @@
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
+#define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive"
+#define DEV_NAME "es1688"
+
+MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("ESS ESx688 AudioDrive");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
"{ESS,ES1688 PnP AudioDrive,pnp:ESS0102},"
@@ -53,189 +56,157 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ESx688 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ESx688 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ESx688 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for ESx688 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ESx688 driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for ESx688 driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
-
-static struct platform_device *devices[SNDRV_CARDS];
+MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
-#define PFX "es1688: "
+static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
+{
+ return enable[n];
+}
-static int __devinit snd_es1688_probe(struct platform_device *pdev)
+static int __devinit snd_es1688_legacy_create(struct snd_card *card,
+ struct device *dev, unsigned int n, struct snd_es1688 **rchip)
{
- int dev = pdev->id;
+ static long possible_ports[] = {0x220, 0x240, 0x260};
static int possible_irqs[] = {5, 9, 10, 7, -1};
static int possible_dmas[] = {1, 3, 0, -1};
- int xirq, xdma, xmpu_irq;
- struct snd_card *card;
- struct snd_es1688 *chip;
- struct snd_opl3 *opl3;
- struct snd_pcm *pcm;
- int err;
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
-
- xirq = irq[dev];
- if (xirq == SNDRV_AUTO_IRQ) {
- if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- err = -EBUSY;
- goto _err;
+
+ int i, error;
+
+ if (irq[n] == SNDRV_AUTO_IRQ) {
+ irq[n] = snd_legacy_find_free_irq(possible_irqs);
+ if (irq[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
+ dev->bus_id);
+ return -EBUSY;
}
}
- xmpu_irq = mpu_irq[dev];
- xdma = dma8[dev];
- if (xdma == SNDRV_AUTO_DMA) {
- if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
- err = -EBUSY;
- goto _err;
+ if (dma8[n] == SNDRV_AUTO_DMA) {
+ dma8[n] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma8[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free DMA\n",
+ dev->bus_id);
+ return -EBUSY;
}
}
- if (port[dev] != SNDRV_AUTO_PORT) {
- if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
- xirq, xmpu_irq, xdma,
- ES1688_HW_AUTO, &chip)) < 0)
- goto _err;
- } else {
- /* auto-probe legacy ports */
- static unsigned long possible_ports[] = {
- 0x220, 0x240, 0x260,
- };
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- err = snd_es1688_create(card, possible_ports[i],
- mpu_port[dev],
- xirq, xmpu_irq, xdma,
- ES1688_HW_AUTO, &chip);
- if (err >= 0) {
- port[dev] = possible_ports[i];
- break;
- }
- }
- if (i >= ARRAY_SIZE(possible_ports))
- goto _err;
- }
+ if (port[n] != SNDRV_AUTO_PORT)
+ return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+ mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
+
+ i = 0;
+ do {
+ port[n] = possible_ports[i];
+ error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+ mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
+ } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
+
+ return error;
+}
+
+static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
+{
+ struct snd_card *card;
+ struct snd_es1688 *chip;
+ struct snd_opl3 *opl3;
+ struct snd_pcm *pcm;
+ int error;
+
+ card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+ if (!card)
+ return -EINVAL;
+
+ error = snd_es1688_legacy_create(card, dev, n, &chip);
+ if (error < 0)
+ goto out;
- if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
- goto _err;
+ error = snd_es1688_pcm(chip, 0, &pcm);
+ if (error < 0)
+ goto out;
- if ((err = snd_es1688_mixer(chip)) < 0)
- goto _err;
+ error = snd_es1688_mixer(chip);
+ if (error < 0)
+ goto out;
strcpy(card->driver, "ES1688");
strcpy(card->shortname, pcm->name);
- sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);
-
- if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
- printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port);
- } else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
- goto _err;
+ sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name,
+ chip->port, chip->irq, chip->dma8);
+
+ if (snd_opl3_create(card, chip->port, chip->port + 2,
+ OPL3_HW_OPL3, 0, &opl3) < 0)
+ printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n",
+ dev->bus_id, chip->port);
+ else {
+ error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (error < 0)
+ goto out;
}
- if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
- chip->mpu_port, 0,
- xmpu_irq,
- IRQF_DISABLED,
- NULL)) < 0)
- goto _err;
+ if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
+ chip->mpu_port > 0) {
+ error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
+ chip->mpu_port, 0,
+ mpu_irq[n], IRQF_DISABLED, NULL);
+ if (error < 0)
+ goto out;
}
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, dev);
- if ((err = snd_card_register(card)) < 0)
- goto _err;
+ error = snd_card_register(card);
+ if (error < 0)
+ goto out;
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(dev, card);
return 0;
- _err:
- snd_card_free(card);
- return err;
+out: snd_card_free(card);
+ return error;
}
-static int __devexit snd_es1688_remove(struct platform_device *devptr)
+static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(dev));
+ dev_set_drvdata(dev, NULL);
return 0;
}
-#define ES1688_DRIVER "snd_es1688"
-
-static struct platform_driver snd_es1688_driver = {
+static struct isa_driver snd_es1688_driver = {
+ .match = snd_es1688_match,
.probe = snd_es1688_probe,
- .remove = __devexit_p(snd_es1688_remove),
- /* FIXME: suspend/resume */
+ .remove = snd_es1688_remove,
+#if 0 /* FIXME */
+ .suspend = snd_es1688_suspend,
+ .resume = snd_es1688_resume,
+#endif
.driver = {
- .name = ES1688_DRIVER
- },
+ .name = DEV_NAME
+ }
};
-static void __init_or_module snd_es1688_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_es1688_driver);
-}
-
static int __init alsa_card_es1688_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_es1688_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(ES1688_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n");
-#endif
- snd_es1688_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
}
static void __exit alsa_card_es1688_exit(void)
{
- snd_es1688_unregister_all();
+ isa_unregister_driver(&snd_es1688_driver);
}
-module_init(alsa_card_es1688_init)
-module_exit(alsa_card_es1688_exit)
+module_init(alsa_card_es1688_init);
+module_exit(alsa_card_es1688_exit);
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 725c115ff97..d2a9c7df0ce 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -80,7 +80,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/isapnp.h>
@@ -2035,8 +2035,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
module_param_array(dma2, int, NULL, 0444);
MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
-static struct platform_device *platform_devices[SNDRV_CARDS];
-
#ifdef CONFIG_PNP
static int pnp_registered, pnpc_registered;
@@ -2237,7 +2235,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
return snd_card_register(card);
}
-static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
+{
+ return enable[dev] && !is_isapnp_selected(dev);
+}
+
+static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr)
{
struct snd_card *card;
int err;
@@ -2245,18 +2248,17 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d
card = snd_es18xx_card_new(dev);
if (! card)
return -ENOMEM;
- snd_card_set_dev(card, &devptr->dev);
+ snd_card_set_dev(card, devptr);
if ((err = snd_audiodrive_probe(card, dev)) < 0) {
snd_card_free(card);
return err;
}
- platform_set_drvdata(devptr, card);
+ dev_set_drvdata(devptr, card);
return 0;
}
-static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
{
- int dev = pdev->id;
int err;
static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
static int possible_dmas[] = {1, 0, 3, 5, -1};
@@ -2281,13 +2283,13 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
}
if (port[dev] != SNDRV_AUTO_PORT) {
- return snd_es18xx_nonpnp_probe1(dev, pdev);
+ return snd_es18xx_isa_probe1(dev, pdev);
} else {
static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280};
int i;
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
port[dev] = possible_ports[i];
- err = snd_es18xx_nonpnp_probe1(dev, pdev);
+ err = snd_es18xx_isa_probe1(dev, pdev);
if (! err)
return 0;
}
@@ -2295,43 +2297,44 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
}
}
-static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_es18xx_isa_remove(struct device *devptr,
+ unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n,
+ pm_message_t state)
{
- return snd_es18xx_suspend(platform_get_drvdata(dev), state);
+ return snd_es18xx_suspend(dev_get_drvdata(dev), state);
}
-static int snd_es18xx_nonpnp_resume(struct platform_device *dev)
+static int snd_es18xx_isa_resume(struct device *dev, unsigned int n)
{
- return snd_es18xx_resume(platform_get_drvdata(dev));
+ return snd_es18xx_resume(dev_get_drvdata(dev));
}
#endif
-#define ES18XX_DRIVER "snd_es18xx"
+#define DEV_NAME "es18xx"
-static struct platform_driver snd_es18xx_nonpnp_driver = {
- .probe = snd_es18xx_nonpnp_probe,
- .remove = __devexit_p(snd_es18xx_nonpnp_remove),
+static struct isa_driver snd_es18xx_isa_driver = {
+ .match = snd_es18xx_isa_match,
+ .probe = snd_es18xx_isa_probe,
+ .remove = __devexit_p(snd_es18xx_isa_remove),
#ifdef CONFIG_PM
- .suspend = snd_es18xx_nonpnp_suspend,
- .resume = snd_es18xx_nonpnp_resume,
+ .suspend = snd_es18xx_isa_suspend,
+ .resume = snd_es18xx_isa_resume,
#endif
.driver = {
- .name = ES18XX_DRIVER
+ .name = DEV_NAME
},
};
#ifdef CONFIG_PNP
-static unsigned int __devinitdata es18xx_pnp_devices;
-
static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
const struct pnp_device_id *id)
{
@@ -2362,7 +2365,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
}
pnp_set_drvdata(pdev, card);
dev++;
- es18xx_pnp_devices++;
return 0;
}
@@ -2424,7 +2426,6 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
pnp_set_card_drvdata(pcard, card);
dev++;
- es18xx_pnp_devices++;
return 0;
}
@@ -2460,44 +2461,14 @@ static struct pnp_card_driver es18xx_pnpc_driver = {
};
#endif /* CONFIG_PNP */
-static void __init_or_module snd_es18xx_unregister_all(void)
-{
- int i;
-
-#ifdef CONFIG_PNP
- if (pnpc_registered)
- pnp_unregister_card_driver(&es18xx_pnpc_driver);
- if (pnp_registered)
- pnp_unregister_driver(&es18xx_pnp_driver);
-#endif
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_es18xx_nonpnp_driver);
-}
-
static int __init alsa_card_es18xx_init(void)
{
- int i, err, cards = 0;
+ int err;
- if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
+ err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
+ if (err < 0)
return err;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i] || is_isapnp_selected(i))
- continue;
- device = platform_device_register_simple(ES18XX_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- cards++;
- }
-
#ifdef CONFIG_PNP
err = pnp_register_driver(&es18xx_pnp_driver);
if (!err)
@@ -2505,22 +2476,19 @@ static int __init alsa_card_es18xx_init(void)
err = pnp_register_card_driver(&es18xx_pnpc_driver);
if (!err)
pnpc_registered = 1;
- cards += es18xx_pnp_devices;
-#endif
-
- if(!cards) {
-#ifdef MODULE
- snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n");
#endif
- snd_es18xx_unregister_all();
- return -ENODEV;
- }
return 0;
}
static void __exit alsa_card_es18xx_exit(void)
{
- snd_es18xx_unregister_all();
+#ifdef CONFIG_PNP
+ if (pnpc_registered)
+ pnp_unregister_card_driver(&es18xx_pnpc_driver);
+ if (pnp_registered)
+ pnp_unregister_driver(&es18xx_pnp_driver);
+#endif
+ isa_unregister_driver(&snd_es18xx_isa_driver);
}
module_init(alsa_card_es18xx_init)
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 0395e2e0dd0..8f23f433d49 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -22,7 +22,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/moduleparam.h>
@@ -33,8 +33,11 @@
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
+#define CRD_NAME "Gravis UltraSound Classic"
+#define DEV_NAME "gusclassic"
+
+MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Gravis UltraSound Classic");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}");
@@ -51,32 +54,80 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for GUS Classic driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver.");
+MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver.");
+MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver.");
+MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
+MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
+
+static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n)
+{
+ return enable[n];
+}
+
+static int __devinit snd_gusclassic_create(struct snd_card *card,
+ struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+{
+ static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260};
+ static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
+ static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
+
+ int i, error;
+
+ if (irq[n] == SNDRV_AUTO_IRQ) {
+ irq[n] = snd_legacy_find_free_irq(possible_irqs);
+ if (irq[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
+ dev->bus_id);
+ return -EBUSY;
+ }
+ }
+ if (dma1[n] == SNDRV_AUTO_DMA) {
+ dma1[n] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma1[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free DMA1\n",
+ dev->bus_id);
+ return -EBUSY;
+ }
+ }
+ if (dma2[n] == SNDRV_AUTO_DMA) {
+ dma2[n] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma2[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free DMA2\n",
+ dev->bus_id);
+ return -EBUSY;
+ }
+ }
-static struct platform_device *devices[SNDRV_CARDS];
+ if (port[n] != SNDRV_AUTO_PORT)
+ return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
+ 0, channels[n], pcm_channels[n], 0, rgus);
+ i = 0;
+ do {
+ port[n] = possible_ports[i];
+ error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
+ 0, channels[n], pcm_channels[n], 0, rgus);
+ } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
-#define PFX "gusclassic: "
+ return error;
+}
-static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
+static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus)
{
unsigned char d;
@@ -95,187 +146,104 @@ static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
return 0;
}
-static void __devinit snd_gusclassic_init(int dev, struct snd_gus_card * gus)
-{
- gus->equal_irq = 0;
- gus->codec_flag = 0;
- gus->max_flag = 0;
- gus->joystick_dac = joystick_dac[dev];
-}
-
-static int __devinit snd_gusclassic_probe(struct platform_device *pdev)
+static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n)
{
- int dev = pdev->id;
- static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
- static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
- int xirq, xdma1, xdma2;
struct snd_card *card;
- struct snd_gus_card *gus = NULL;
- int err;
-
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
- if (pcm_channels[dev] < 2)
- pcm_channels[dev] = 2;
-
- xirq = irq[dev];
- if (xirq == SNDRV_AUTO_IRQ) {
- if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
- err = -EBUSY;
- goto _err;
- }
- }
- xdma1 = dma1[dev];
- if (xdma1 == SNDRV_AUTO_DMA) {
- if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
- err = -EBUSY;
- goto _err;
- }
- }
- xdma2 = dma2[dev];
- if (xdma2 == SNDRV_AUTO_DMA) {
- if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
- err = -EBUSY;
- goto _err;
- }
- }
+ struct snd_gus_card *gus;
+ int error;
- if (port[dev] != SNDRV_AUTO_PORT) {
- err = snd_gus_create(card,
- port[dev],
- xirq, xdma1, xdma2,
- 0, channels[dev], pcm_channels[dev],
- 0, &gus);
- } else {
- /* auto-probe legacy ports */
- static unsigned long possible_ports[] = {
- 0x220, 0x230, 0x240, 0x250, 0x260,
- };
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- err = snd_gus_create(card,
- possible_ports[i],
- xirq, xdma1, xdma2,
- 0, channels[dev], pcm_channels[dev],
- 0, &gus);
- if (err >= 0) {
- port[dev] = possible_ports[i];
- break;
- }
- }
- }
- if (err < 0)
- goto _err;
+ card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+ if (!card)
+ return -EINVAL;
- if ((err = snd_gusclassic_detect(gus)) < 0)
- goto _err;
+ if (pcm_channels[n] < 2)
+ pcm_channels[n] = 2;
- snd_gusclassic_init(dev, gus);
- if ((err = snd_gus_initialize(gus)) < 0)
- goto _err;
+ error = snd_gusclassic_create(card, dev, n, &gus);
+ if (error < 0)
+ goto out;
+ error = snd_gusclassic_detect(gus);
+ if (error < 0)
+ goto out;
+
+ gus->joystick_dac = joystick_dac[n];
+
+ error = snd_gus_initialize(gus);
+ if (error < 0)
+ goto out;
+
+ error = -ENODEV;
if (gus->max_flag || gus->ess_flag) {
- snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
- err = -ENODEV;
- goto _err;
+ snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was "
+ "not detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
+ goto out;
}
- if ((err = snd_gf1_new_mixer(gus)) < 0)
- goto _err;
+ error = snd_gf1_new_mixer(gus);
+ if (error < 0)
+ goto out;
- if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0)
- goto _err;
+ error = snd_gf1_pcm_new(gus, 0, 0, NULL);
+ if (error < 0)
+ goto out;
if (!gus->ace_flag) {
- if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
- goto _err;
+ error = snd_gf1_rawmidi_new(gus, 0, NULL);
+ if (error < 0)
+ goto out;
}
- sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1);
- if (xdma2 >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
- snd_card_set_dev(card, &pdev->dev);
+ sprintf(card->longname + strlen(card->longname),
+ " at 0x%lx, irq %d, dma %d",
+ gus->gf1.port, gus->gf1.irq, gus->gf1.dma1);
- if ((err = snd_card_register(card)) < 0)
- goto _err;
+ if (gus->gf1.dma2 >= 0)
+ sprintf(card->longname + strlen(card->longname),
+ "&%d", gus->gf1.dma2);
- platform_set_drvdata(pdev, card);
+ snd_card_set_dev(card, dev);
+
+ error = snd_card_register(card);
+ if (error < 0)
+ goto out;
+
+ dev_set_drvdata(dev, card);
return 0;
- _err:
- snd_card_free(card);
- return err;
+out: snd_card_free(card);
+ return error;
}
-static int __devexit snd_gusclassic_remove(struct platform_device *devptr)
+static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(dev));
+ dev_set_drvdata(dev, NULL);
return 0;
}
-#define GUSCLASSIC_DRIVER "snd_gusclassic"
-
-static struct platform_driver snd_gusclassic_driver = {
+static struct isa_driver snd_gusclassic_driver = {
+ .match = snd_gusclassic_match,
.probe = snd_gusclassic_probe,
.remove = __devexit_p(snd_gusclassic_remove),
- /* FIXME: suspend/resume */
+#if 0 /* FIXME */
+ .suspend = snd_gusclassic_suspend,
+ .remove = snd_gusclassic_remove,
+#endif
.driver = {
- .name = GUSCLASSIC_DRIVER
- },
+ .name = DEV_NAME
+ }
};
-static void __init_or_module snd_gusclassic_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_gusclassic_driver);
-}
-
static int __init alsa_card_gusclassic_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_gusclassic_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(GUSCLASSIC_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "GUS Classic soundcard not found or device busy\n");
-#endif
- snd_gusclassic_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS);
}
static void __exit alsa_card_gusclassic_exit(void)
{
- snd_gusclassic_unregister_all();
+ isa_unregister_driver(&snd_gusclassic_driver);
}
-module_init(alsa_card_gusclassic_init)
-module_exit(alsa_card_gusclassic_exit)
+module_init(alsa_card_gusclassic_init);
+module_exit(alsa_card_gusclassic_exit);
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 4f55fc3e66c..0aeaa6cf6cf 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -22,7 +22,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/moduleparam.h>
@@ -37,8 +37,11 @@
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
+#define CRD_NAME "Gravis UltraSound Extreme"
+#define DEV_NAME "gusextreme"
+
+MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Gravis UltraSound Extreme");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}");
@@ -59,43 +62,107 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for GUS Extreme driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param_array(gf1_port, long, NULL, 0444);
-MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional).");
+MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional).");
module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param_array(mpu_irq, int, NULL, 0444);
-MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for GUS Extreme driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
module_param_array(gf1_irq, int, NULL, 0444);
-MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver.");
+MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver.");
module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver.");
+MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver.");
+MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver.");
module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver.");
+MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver.");
+MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
+MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
+
+static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
+{
+ return enable[n];
+}
+
+static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
+ struct device *dev, unsigned int n, struct snd_es1688 **rchip)
+{
+ static long possible_ports[] = {0x220, 0x240, 0x260};
+ static int possible_irqs[] = {5, 9, 10, 7, -1};
+ static int possible_dmas[] = {1, 3, 0, -1};
+
+ int i, error;
+
+ if (irq[n] == SNDRV_AUTO_IRQ) {
+ irq[n] = snd_legacy_find_free_irq(possible_irqs);
+ if (irq[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free IRQ "
+ "for ES1688\n", dev->bus_id);
+ return -EBUSY;
+ }
+ }
+ if (dma8[n] == SNDRV_AUTO_DMA) {
+ dma8[n] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma8[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free DMA "
+ "for ES1688\n", dev->bus_id);
+ return -EBUSY;
+ }
+ }
-static struct platform_device *devices[SNDRV_CARDS];
+ if (port[n] != SNDRV_AUTO_PORT)
+ return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+ mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
+ i = 0;
+ do {
+ port[n] = possible_ports[i];
+ error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+ mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
+ } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
-#define PFX "gusextreme: "
+ return error;
+}
-static int __devinit snd_gusextreme_detect(int dev,
- struct snd_card *card,
- struct snd_gus_card * gus,
- struct snd_es1688 *es1688)
+static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card,
+ struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+{
+ static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1};
+ static int possible_dmas[] = {5, 6, 7, 3, 1, -1};
+
+ if (gf1_irq[n] == SNDRV_AUTO_IRQ) {
+ gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs);
+ if (gf1_irq[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free IRQ "
+ "for GF1\n", dev->bus_id);
+ return -EBUSY;
+ }
+ }
+ if (dma1[n] == SNDRV_AUTO_DMA) {
+ dma1[n] = snd_legacy_find_free_dma(possible_dmas);
+ if (dma1[n] < 0) {
+ snd_printk(KERN_ERR "%s: unable to find a free DMA "
+ "for GF1\n", dev->bus_id);
+ return -EBUSY;
+ }
+ }
+ return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1,
+ 0, channels[n], pcm_channels[n], 0, rgus);
+}
+
+static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
+ struct snd_es1688 *es1688)
{
unsigned long flags;
unsigned char d;
@@ -117,12 +184,13 @@ static int __devinit snd_gusextreme_detect(int dev,
spin_lock_irqsave(&es1688->mixer_lock, flags);
snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */
spin_unlock_irqrestore(&es1688->mixer_lock, flags);
+
spin_lock_irqsave(&es1688->reg_lock, flags);
- outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
+ outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
outb(0, 0x201);
- outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
+ outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
outb(0, 0x201);
- outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
+ outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
spin_unlock_irqrestore(&es1688->reg_lock, flags);
udelay(100);
@@ -139,253 +207,172 @@ static int __devinit snd_gusextreme_detect(int dev,
snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
return -EIO;
}
- return 0;
-}
-static void __devinit snd_gusextreme_init(int dev, struct snd_gus_card * gus)
-{
- gus->joystick_dac = joystick_dac[dev];
+ return 0;
}
static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip)
{
struct snd_card *card = chip->card;
struct snd_ctl_elem_id id1, id2;
- int err;
+ int error;
memset(&id1, 0, sizeof(id1));
memset(&id2, 0, sizeof(id2));
id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+
/* reassign AUX to SYNTHESIZER */
strcpy(id1.name, "Aux Playback Volume");
strcpy(id2.name, "Synth Playback Volume");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
+ error = snd_ctl_rename_id(card, &id1, &id2);
+ if (error < 0)
+ return error;
+
/* reassign Master Playback Switch to Synth Playback Switch */
strcpy(id1.name, "Master Playback Switch");
strcpy(id2.name, "Synth Playback Switch");
- if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
- return err;
+ error = snd_ctl_rename_id(card, &id1, &id2);
+ if (error < 0)
+ return error;
+
return 0;
}
-static int __devinit snd_gusextreme_probe(struct platform_device *pdev)
+static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
{
- int dev = pdev->id;
- static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
- static int possible_ess_dmas[] = {1, 3, 0, -1};
- static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
- static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
- int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
struct snd_card *card;
struct snd_gus_card *gus;
struct snd_es1688 *es1688;
struct snd_opl3 *opl3;
- int err;
+ int error;
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+ if (!card)
+ return -EINVAL;
- xgf1_irq = gf1_irq[dev];
- if (xgf1_irq == SNDRV_AUTO_IRQ) {
- if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n");
- err = -EBUSY;
- goto out;
- }
- }
- xess_irq = irq[dev];
- if (xess_irq == SNDRV_AUTO_IRQ) {
- if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n");
- err = -EBUSY;
- goto out;
- }
- }
- if (mpu_port[dev] == SNDRV_AUTO_PORT)
- mpu_port[dev] = 0;
- xmpu_irq = mpu_irq[dev];
- if (xmpu_irq > 15)
- xmpu_irq = -1;
- xgf1_dma = dma1[dev];
- if (xgf1_dma == SNDRV_AUTO_DMA) {
- if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n");
- err = -EBUSY;
- goto out;
- }
- }
- xess_dma = dma8[dev];
- if (xess_dma == SNDRV_AUTO_DMA) {
- if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
- snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n");
- err = -EBUSY;
- goto out;
- }
- }
+ if (mpu_port[n] == SNDRV_AUTO_PORT)
+ mpu_port[n] = 0;
- if (port[dev] != SNDRV_AUTO_PORT) {
- err = snd_es1688_create(card, port[dev], mpu_port[dev],
- xess_irq, xmpu_irq, xess_dma,
- ES1688_HW_1688, &es1688);
- } else {
- /* auto-probe legacy ports */
- static unsigned long possible_ports[] = {0x220, 0x240, 0x260};
- int i;
- for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
- err = snd_es1688_create(card,
- possible_ports[i],
- mpu_port[dev],
- xess_irq, xmpu_irq, xess_dma,
- ES1688_HW_1688, &es1688);
- if (err >= 0) {
- port[dev] = possible_ports[i];
- break;
- }
- }
- }
- if (err < 0)
+ if (mpu_irq[n] > 15)
+ mpu_irq[n] = -1;
+
+ error = snd_gusextreme_es1688_create(card, dev, n, &es1688);
+ if (error < 0)
goto out;
- if (gf1_port[dev] < 0)
- gf1_port[dev] = port[dev] + 0x20;
- if ((err = snd_gus_create(card,
- gf1_port[dev],
- xgf1_irq,
- xgf1_dma,
- -1,
- 0, channels[dev],
- pcm_channels[dev], 0,
- &gus)) < 0)
+ if (gf1_port[n] < 0)
+ gf1_port[n] = es1688->port + 0x20;
+
+ error = snd_gusextreme_gus_card_create(card, dev, n, &gus);
+ if (error < 0)
goto out;
- if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0)
+ error = snd_gusextreme_detect(gus, es1688);
+ if (error < 0)
goto out;
- snd_gusextreme_init(dev, gus);
- if ((err = snd_gus_initialize(gus)) < 0)
+ gus->joystick_dac = joystick_dac[n];
+
+ error = snd_gus_initialize(gus);
+ if (error < 0)
goto out;
+ error = -ENODEV;
if (!gus->ess_flag) {
- snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
- err = -ENODEV;
+ snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not "
+ "detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
goto out;
}
- if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0)
+ gus->codec_flag = 1;
+
+ error = snd_es1688_pcm(es1688, 0, NULL);
+ if (error < 0)
goto out;
- if ((err = snd_es1688_mixer(es1688)) < 0)
+ error = snd_es1688_mixer(es1688);
+ if (error < 0)
goto out;
snd_component_add(card, "ES1688");
- if (pcm_channels[dev] > 0) {
- if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+
+ if (pcm_channels[n] > 0) {
+ error = snd_gf1_pcm_new(gus, 1, 1, NULL);
+ if (error < 0)
goto out;
}
- if ((err = snd_gf1_new_mixer(gus)) < 0)
+
+ error = snd_gf1_new_mixer(gus);
+ if (error < 0)
goto out;
- if ((err = snd_gusextreme_mixer(es1688)) < 0)
+ error = snd_gusextreme_mixer(es1688);
+ if (error < 0)
goto out;
if (snd_opl3_create(card, es1688->port, es1688->port + 2,
- OPL3_HW_OPL3, 0, &opl3) < 0) {
- printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
- } else {
- if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
+ OPL3_HW_OPL3, 0, &opl3) < 0)
+ printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n",
+ dev->bus_id, es1688->port);
+ else {
+ error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
+ if (error < 0)
goto out;
}
- if (es1688->mpu_port >= 0x300 &&
- (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
- es1688->mpu_port, 0,
- xmpu_irq,
- IRQF_DISABLED,
- NULL)) < 0)
- goto out;
+ if (es1688->mpu_port >= 0x300) {
+ error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
+ es1688->mpu_port, 0,
+ mpu_irq[n], IRQF_DISABLED, NULL);
+ if (error < 0)
+ goto out;
+ }
- sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
- es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
+ sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, "
+ "irq %i&%i, dma %i&%i", es1688->port,
+ gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8);
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, dev);
- if ((err = snd_card_register(card)) < 0)
+ error = snd_card_register(card);
+ if (error < 0)
goto out;
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(dev, card);
return 0;
- out:
- snd_card_free(card);
- return err;
+out: snd_card_free(card);
+ return error;
}
-static int __devexit snd_gusextreme_remove(struct platform_device *devptr)
+static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(dev));
+ dev_set_drvdata(dev, NULL);
return 0;
}
-#define GUSEXTREME_DRIVER "snd_gusextreme"
-
-static struct platform_driver snd_gusextreme_driver = {
+static struct isa_driver snd_gusextreme_driver = {
+ .match = snd_gusextreme_match,
.probe = snd_gusextreme_probe,
- .remove = __devexit_p(snd_gusextreme_remove),
- /* FIXME: suspend/resume */
+ .remove = snd_gusextreme_remove,
+#if 0 /* FIXME */
+ .suspend = snd_gusextreme_suspend,
+ .resume = snd_gusextreme_resume,
+#endif
.driver = {
- .name = GUSEXTREME_DRIVER
- },
+ .name = DEV_NAME
+ }
};
-static void __init_or_module snd_gusextreme_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_gusextreme_driver);
-}
-
static int __init alsa_card_gusextreme_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_gusextreme_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(GUSEXTREME_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n");
-#endif
- snd_gusextreme_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS);
}
static void __exit alsa_card_gusextreme_exit(void)
{
- snd_gusextreme_unregister_all();
+ isa_unregister_driver(&snd_gusextreme_driver);
}
-module_init(alsa_card_gusextreme_init)
-module_exit(alsa_card_gusextreme_exit)
+module_init(alsa_card_gusextreme_init);
+module_exit(alsa_card_gusextreme_exit);
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index d1ad90ca035..708783d4351 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -22,7 +22,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/moduleparam.h>
@@ -72,8 +72,6 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver.");
module_param_array(pcm_channels, int, NULL, 0444);
MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
-static struct platform_device *devices[SNDRV_CARDS];
-
struct snd_gusmax {
int irq;
struct snd_card *card;
@@ -205,9 +203,13 @@ static void snd_gusmax_free(struct snd_card *card)
free_irq(maxcard->irq, (void *)maxcard);
}
-static int __devinit snd_gusmax_probe(struct platform_device *pdev)
+static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev)
+{
+ return enable[dev];
+}
+
+static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
{
- int dev = pdev->id;
static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
int xirq, xdma1, xdma2, err;
@@ -333,7 +335,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
if (xdma2 >= 0)
sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, pdev);
if ((err = snd_card_register(card)) < 0)
goto _err;
@@ -341,7 +343,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
maxcard->gus = gus;
maxcard->cs4231 = cs4231;
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(pdev, card);
return 0;
_err:
@@ -349,70 +351,33 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
return err;
}
-static int __devexit snd_gusmax_remove(struct platform_device *devptr)
+static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
-#define GUSMAX_DRIVER "snd_gusmax"
+#define DEV_NAME "gusmax"
-static struct platform_driver snd_gusmax_driver = {
+static struct isa_driver snd_gusmax_driver = {
+ .match = snd_gusmax_match,
.probe = snd_gusmax_probe,
.remove = __devexit_p(snd_gusmax_remove),
/* FIXME: suspend/resume */
.driver = {
- .name = GUSMAX_DRIVER
+ .name = DEV_NAME
},
};
-static void __init_or_module snd_gusmax_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_gusmax_driver);
-}
-
static int __init alsa_card_gusmax_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_gusmax_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(GUSMAX_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "GUS MAX soundcard not found or device busy\n");
-#endif
- snd_gusmax_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS);
}
static void __exit alsa_card_gusmax_exit(void)
{
- snd_gusmax_unregister_all();
+ isa_unregister_driver(&snd_gusmax_driver);
}
module_init(alsa_card_gusmax_init)
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 4ec2d79431f..3e465725553 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -25,7 +25,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pnp.h>
@@ -115,9 +115,6 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver.");
module_param_array(effect, int, NULL, 0444);
MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
-
struct snd_interwave {
int irq;
struct snd_card *card;
@@ -138,6 +135,7 @@ struct snd_interwave {
#ifdef CONFIG_PNP
+static int pnp_registered;
static struct pnp_card_device_id snd_interwave_pnpids[] = {
#ifndef SNDRV_STB
@@ -793,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
return 0;
}
-static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr)
{
struct snd_card *card;
int err;
@@ -802,18 +800,30 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device
if (! card)
return -ENOMEM;
- snd_card_set_dev(card, &devptr->dev);
+ snd_card_set_dev(card, devptr);
if ((err = snd_interwave_probe(card, dev)) < 0) {
snd_card_free(card);
return err;
}
- platform_set_drvdata(devptr, card);
+ dev_set_drvdata(devptr, card);
return 0;
}
-static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_interwave_isa_match(struct device *pdev,
+ unsigned int dev)
+{
+ if (!enable[dev])
+ return 0;
+#ifdef CONFIG_PNP
+ if (isapnp[dev])
+ return 0;
+#endif
+ return 1;
+}
+
+static int __devinit snd_interwave_isa_probe(struct device *pdev,
+ unsigned int dev)
{
- int dev = pdev->id;
int err;
static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
@@ -838,13 +848,13 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
}
if (port[dev] != SNDRV_AUTO_PORT)
- return snd_interwave_nonpnp_probe1(dev, pdev);
+ return snd_interwave_isa_probe1(dev, pdev);
else {
static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};
int i;
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
port[dev] = possible_ports[i];
- err = snd_interwave_nonpnp_probe1(dev, pdev);
+ err = snd_interwave_isa_probe1(dev, pdev);
if (! err)
return 0;
}
@@ -852,16 +862,17 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
}
}
-static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
-static struct platform_driver snd_interwave_driver = {
- .probe = snd_interwave_nonpnp_probe,
- .remove = __devexit_p(snd_interwave_nonpnp_remove),
+static struct isa_driver snd_interwave_driver = {
+ .match = snd_interwave_isa_match,
+ .probe = snd_interwave_isa_probe,
+ .remove = __devexit_p(snd_interwave_isa_remove),
/* FIXME: suspend,resume */
.driver = {
.name = INTERWAVE_DRIVER
@@ -869,8 +880,6 @@ static struct platform_driver snd_interwave_driver = {
};
#ifdef CONFIG_PNP
-static unsigned int __devinitdata interwave_pnp_devices;
-
static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
@@ -900,7 +909,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
}
pnp_set_card_drvdata(pcard, card);
dev++;
- interwave_pnp_devices++;
return 0;
}
@@ -921,64 +929,29 @@ static struct pnp_card_driver interwave_pnpc_driver = {
#endif /* CONFIG_PNP */
-static void __init_or_module snd_interwave_unregister_all(void)
-{
- int i;
-
- if (pnp_registered)
- pnp_unregister_card_driver(&interwave_pnpc_driver);
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_interwave_driver);
-}
-
static int __init alsa_card_interwave_init(void)
{
- int i, err, cards = 0;
+ int err;
- if ((err = platform_driver_register(&snd_interwave_driver)) < 0)
+ err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
+ if (err < 0)
return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
#ifdef CONFIG_PNP
- if (isapnp[i])
- continue;
-#endif
- device = platform_device_register_simple(INTERWAVE_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- cards++;
- }
-
/* ISA PnP cards */
err = pnp_register_card_driver(&interwave_pnpc_driver);
- if (!err) {
+ if (!err)
pnp_registered = 1;
- cards += interwave_pnp_devices;;
- }
-
- if (!cards) {
-#ifdef MODULE
- printk(KERN_ERR "InterWave soundcard not found or device busy\n");
#endif
- snd_interwave_unregister_all();
- return -ENODEV;
- }
return 0;
}
static void __exit alsa_card_interwave_exit(void)
{
- snd_interwave_unregister_all();
+#ifdef CONFIG_PNP
+ if (pnp_registered)
+ pnp_unregister_card_driver(&interwave_pnpc_driver);
+#endif
+ isa_unregister_driver(&snd_interwave_driver);
}
module_init(alsa_card_interwave_init)
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index f3db686b1c0..48743eb85fb 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -22,7 +22,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/slab.h>
@@ -91,12 +91,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
module_param_array(opl3sa3_ymode, int, NULL, 0444);
MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
-static struct platform_device *platform_devices[SNDRV_CARDS];
#ifdef CONFIG_PNP
static int pnp_registered;
static int pnpc_registered;
#endif
-static unsigned int snd_opl3sa2_devices;
/* control ports */
#define OPL3SA2_PM_CTRL 0x01
@@ -783,7 +781,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
}
pnp_set_drvdata(pdev, card);
dev++;
- snd_opl3sa2_devices++;
return 0;
}
@@ -850,7 +847,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
}
pnp_set_card_drvdata(pcard, card);
dev++;
- snd_opl3sa2_devices++;
return 0;
}
@@ -884,116 +880,95 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = {
};
#endif /* CONFIG_PNP */
-static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_opl3sa2_isa_match(struct device *pdev,
+ unsigned int dev)
{
- struct snd_card *card;
- int err;
- int dev = pdev->id;
-
+ if (!enable[dev])
+ return 0;
+#ifdef CONFIG_PNP
+ if (isapnp[dev])
+ return 0;
+#endif
if (port[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify port\n");
- return -EINVAL;
+ return 0;
}
if (wss_port[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify wss_port\n");
- return -EINVAL;
+ return 0;
}
if (fm_port[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify fm_port\n");
- return -EINVAL;
+ return 0;
}
if (midi_port[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify midi_port\n");
- return -EINVAL;
+ return 0;
}
+ return 1;
+}
+
+static int __devinit snd_opl3sa2_isa_probe(struct device *pdev,
+ unsigned int dev)
+{
+ struct snd_card *card;
+ int err;
card = snd_opl3sa2_card_new(dev);
if (! card)
return -ENOMEM;
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, pdev);
if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
snd_card_free(card);
return err;
}
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(pdev, card);
return 0;
}
-static int __devexit snd_opl3sa2_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_opl3sa2_isa_remove(struct device *devptr,
+ unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n,
+ pm_message_t state)
{
- return snd_opl3sa2_suspend(platform_get_drvdata(dev), state);
+ return snd_opl3sa2_suspend(dev_get_drvdata(dev), state);
}
-static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev)
+static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n)
{
- return snd_opl3sa2_resume(platform_get_drvdata(dev));
+ return snd_opl3sa2_resume(dev_get_drvdata(dev));
}
#endif
-#define OPL3SA2_DRIVER "snd_opl3sa2"
+#define DEV_NAME "opl3sa2"
-static struct platform_driver snd_opl3sa2_nonpnp_driver = {
- .probe = snd_opl3sa2_nonpnp_probe,
- .remove = __devexit( snd_opl3sa2_nonpnp_remove),
+static struct isa_driver snd_opl3sa2_isa_driver = {
+ .match = snd_opl3sa2_isa_match,
+ .probe = snd_opl3sa2_isa_probe,
+ .remove = __devexit( snd_opl3sa2_isa_remove),
#ifdef CONFIG_PM
- .suspend = snd_opl3sa2_nonpnp_suspend,
- .resume = snd_opl3sa2_nonpnp_resume,
+ .suspend = snd_opl3sa2_isa_suspend,
+ .resume = snd_opl3sa2_isa_resume,
#endif
.driver = {
- .name = OPL3SA2_DRIVER
+ .name = DEV_NAME
},
};
-static void __init_or_module snd_opl3sa2_unregister_all(void)
-{
- int i;
-
-#ifdef CONFIG_PNP
- if (pnpc_registered)
- pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
- if (pnp_registered)
- pnp_unregister_driver(&opl3sa2_pnp_driver);
-#endif
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
-}
-
static int __init alsa_card_opl3sa2_init(void)
{
- int i, err;
+ int err;
- if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
+ err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
+ if (err < 0)
return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
-#ifdef CONFIG_PNP
- if (isapnp[i])
- continue;
-#endif
- device = platform_device_register_simple(OPL3SA2_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- snd_opl3sa2_devices++;
- }
-
#ifdef CONFIG_PNP
err = pnp_register_driver(&opl3sa2_pnp_driver);
if (!err)
@@ -1002,20 +977,18 @@ static int __init alsa_card_opl3sa2_init(void)
if (!err)
pnpc_registered = 1;
#endif
-
- if (!snd_opl3sa2_devices) {
-#ifdef MODULE
- snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
-#endif
- snd_opl3sa2_unregister_all();
- return -ENODEV;
- }
return 0;
}
static void __exit alsa_card_opl3sa2_exit(void)
{
- snd_opl3sa2_unregister_all();
+#ifdef CONFIG_PNP
+ if (pnpc_registered)
+ pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+ if (pnp_registered)
+ pnp_unregister_driver(&opl3sa2_pnp_driver);
+#endif
+ isa_unregister_driver(&snd_opl3sa2_isa_driver);
}
module_init(alsa_card_opl3sa2_init)
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 1dd98375ac8..cd29b30b362 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -25,7 +25,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/ioport.h>
@@ -137,10 +137,6 @@ struct snd_miro {
static void snd_miro_proc_init(struct snd_miro * miro);
-#define DRIVER_NAME "snd-miro"
-
-static struct platform_device *device;
-
static char * snd_opti9xx_names[] = {
"unkown",
"82C928", "82C929",
@@ -558,7 +554,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
return change;
}
-static struct snd_kcontrol_new snd_miro_controls[] = {
+static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = {
MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
@@ -570,7 +566,7 @@ MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2),
/* Equalizer with seven bands (only PCM20)
from -12dB up to +12dB on each band */
-static struct snd_kcontrol_new snd_miro_eq_controls[] = {
+static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = {
MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
@@ -580,15 +576,15 @@ MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6),
MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
};
-static struct snd_kcontrol_new snd_miro_radio_control[] = {
+static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = {
MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
};
-static struct snd_kcontrol_new snd_miro_line_control[] = {
+static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = {
MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
};
-static struct snd_kcontrol_new snd_miro_preamp_control[] = {
+static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Mic Boost",
@@ -598,7 +594,7 @@ static struct snd_kcontrol_new snd_miro_preamp_control[] = {
.put = snd_miro_put_preamp,
}};
-static struct snd_kcontrol_new snd_miro_amp_control[] = {
+static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Line Boost",
@@ -608,7 +604,7 @@ static struct snd_kcontrol_new snd_miro_amp_control[] = {
.put = snd_miro_put_amp,
}};
-static struct snd_kcontrol_new snd_miro_capture_control[] = {
+static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Capture Switch",
@@ -618,7 +614,7 @@ static struct snd_kcontrol_new snd_miro_capture_control[] = {
.put = snd_miro_put_capture,
}};
-static unsigned char aci_init_values[][2] __initdata = {
+static unsigned char aci_init_values[][2] __devinitdata = {
{ ACI_SET_MUTE, 0x00 },
{ ACI_SET_POWERAMP, 0x00 },
{ ACI_SET_PREAMP, 0x00 },
@@ -641,7 +637,7 @@ static unsigned char aci_init_values[][2] __initdata = {
{ ACI_SET_MASTER + 1, 0x20 },
};
-static int __init snd_set_aci_init_values(struct snd_miro *miro)
+static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
{
int idx, error;
@@ -751,7 +747,8 @@ static long snd_legacy_find_free_ioport(long *port_table, long size)
return -1;
}
-static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware)
+static int __devinit snd_miro_init(struct snd_miro *chip,
+ unsigned short hardware)
{
static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
@@ -962,7 +959,7 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp);
}
-static void __init snd_miro_proc_init(struct snd_miro * miro)
+static void __devinit snd_miro_proc_init(struct snd_miro * miro)
{
struct snd_info_entry *entry;
@@ -974,7 +971,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro)
* Init
*/
-static int __init snd_miro_configure(struct snd_miro *chip)
+static int __devinit snd_miro_configure(struct snd_miro *chip)
{
unsigned char wss_base_bits;
unsigned char irq_bits;
@@ -1131,7 +1128,8 @@ __skip_mpu:
return 0;
}
-static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip)
+static int __devinit snd_card_miro_detect(struct snd_card *card,
+ struct snd_miro *chip)
{
int i, err;
unsigned char value;
@@ -1157,7 +1155,8 @@ static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *c
return -ENODEV;
}
-static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro)
+static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
+ struct snd_miro * miro)
{
unsigned char regval;
int i;
@@ -1213,7 +1212,12 @@ static void snd_card_miro_free(struct snd_card *card)
release_and_free_resource(miro->res_mc_base);
}
-static int __init snd_miro_probe(struct platform_device *devptr)
+static int __devinit snd_miro_match(struct device *devptr, unsigned int n)
+{
+ return 1;
+}
+
+static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
{
static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
@@ -1399,56 +1403,44 @@ static int __init snd_miro_probe(struct platform_device *devptr)
return error;
}
- snd_card_set_dev(card, &devptr->dev);
+ snd_card_set_dev(card, devptr);
if ((error = snd_card_register(card))) {
snd_card_free(card);
return error;
}
- platform_set_drvdata(devptr, card);
+ dev_set_drvdata(devptr, card);
return 0;
}
-static int __devexit snd_miro_remove(struct platform_device *devptr)
+static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
-static struct platform_driver snd_miro_driver = {
+#define DEV_NAME "miro"
+
+static struct isa_driver snd_miro_driver = {
+ .match = snd_miro_match,
.probe = snd_miro_probe,
.remove = __devexit_p(snd_miro_remove),
/* FIXME: suspend/resume */
.driver = {
- .name = DRIVER_NAME
+ .name = DEV_NAME
},
};
static int __init alsa_card_miro_init(void)
{
- int error;
-
- if ((error = platform_driver_register(&snd_miro_driver)) < 0)
- return error;
- device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
- if (! IS_ERR(device)) {
- if (platform_get_drvdata(device))
- return 0;
- platform_device_unregister(device);
- }
-#ifdef MODULE
- printk(KERN_ERR "no miro soundcard found\n");
-#endif
- platform_driver_unregister(&snd_miro_driver);
- return PTR_ERR(device);
+ return isa_register_driver(&snd_miro_driver, 1);
}
static void __exit alsa_card_miro_exit(void)
{
- platform_device_unregister(device);
- platform_driver_unregister(&snd_miro_driver);
+ isa_unregister_driver(&snd_miro_driver);
}
module_init(alsa_card_miro_init)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index df227377c33..60c120ffb9d 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -26,7 +26,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pnp.h>
@@ -259,7 +259,6 @@ struct snd_opti9xx {
};
static int snd_opti9xx_pnp_is_probed;
-static struct platform_device *snd_opti9xx_platform_device;
#ifdef CONFIG_PNP
@@ -281,10 +280,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
#endif /* CONFIG_PNP */
#ifdef OPTi93X
-#define DRIVER_NAME "snd-card-opti93x"
+#define DEV_NAME "opti93x"
#else
-#define DRIVER_NAME "snd-card-opti92x"
-#endif /* OPTi93X */
+#define DEV_NAME "opti92x"
+#endif
static char * snd_opti9xx_names[] = {
"unkown",
@@ -294,7 +293,7 @@ static char * snd_opti9xx_names[] = {
};
-static long __init snd_legacy_find_free_ioport(long *port_table, long size)
+static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
{
while (*port_table != -1) {
if (request_region(*port_table, size, "ALSA test")) {
@@ -306,7 +305,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size)
return -1;
}
-static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware)
+static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
+ unsigned short hardware)
{
static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
@@ -451,7 +451,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
-static int __init snd_opti9xx_configure(struct snd_opti9xx *chip)
+static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
{
unsigned char wss_base_bits;
unsigned char irq_bits;
@@ -934,10 +934,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_STOP:
{
unsigned int what = 0;
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == chip->playback_substream) {
what |= OPTi93X_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
@@ -1291,7 +1289,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip,
}
codec->dma2 = chip->dma2;
- if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) {
+ if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) {
snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
snd_opti93x_free(codec);
return -EBUSY;
@@ -1561,7 +1559,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
return change;
}
-static struct snd_kcontrol_new snd_opti93x_controls[] = {
+static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = {
OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1),
OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
@@ -1622,7 +1620,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip)
#endif /* OPTi93X */
-static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip)
+static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
+ struct snd_opti9xx *chip)
{
int i, err;
@@ -1676,8 +1675,9 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti
}
#ifdef CONFIG_PNP
-static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card,
- const struct pnp_card_device_id *pid)
+static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
+ struct pnp_card_link *card,
+ const struct pnp_card_device_id *pid)
{
struct pnp_dev *pdev;
struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
@@ -1778,7 +1778,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
release_and_free_resource(chip->res_mc_base);
}
-static int __init snd_opti9xx_probe(struct snd_card *card)
+static int __devinit snd_opti9xx_probe(struct snd_card *card)
{
static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
int error;
@@ -1924,7 +1924,18 @@ static struct snd_card *snd_opti9xx_card_new(void)
return card;
}
-static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
+static int __devinit snd_opti9xx_isa_match(struct device *devptr,
+ unsigned int dev)
+{
+ if (snd_opti9xx_pnp_is_probed)
+ return 0;
+ if (isapnp)
+ return 0;
+ return 1;
+}
+
+static int __devinit snd_opti9xx_isa_probe(struct device *devptr,
+ unsigned int dev)
{
struct snd_card *card;
int error;
@@ -1940,9 +1951,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
#endif /* CS4231 || OPTi93X */
- if (snd_opti9xx_pnp_is_probed)
- return -EBUSY;
-
if (mpu_port == SNDRV_AUTO_PORT) {
if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
@@ -1984,34 +1992,36 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
snd_card_free(card);
return error;
}
- snd_card_set_dev(card, &devptr->dev);
+ snd_card_set_dev(card, devptr);
if ((error = snd_opti9xx_probe(card)) < 0) {
snd_card_free(card);
return error;
}
- platform_set_drvdata(devptr, card);
+ dev_set_drvdata(devptr, card);
return 0;
}
-static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
+ unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
-static struct platform_driver snd_opti9xx_driver = {
- .probe = snd_opti9xx_nonpnp_probe,
- .remove = __devexit_p(snd_opti9xx_nonpnp_remove),
+static struct isa_driver snd_opti9xx_driver = {
+ .match = snd_opti9xx_isa_match,
+ .probe = snd_opti9xx_isa_probe,
+ .remove = __devexit_p(snd_opti9xx_isa_remove),
/* FIXME: suspend/resume */
.driver = {
- .name = DRIVER_NAME
+ .name = DEV_NAME
},
};
#ifdef CONFIG_PNP
-static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
- const struct pnp_card_device_id *pid)
+static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
+ const struct pnp_card_device_id *pid)
{
struct snd_card *card;
int error, hw;
@@ -2074,11 +2084,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
};
#endif
-#ifdef CONFIG_PNP
-#define is_isapnp_selected() isapnp
-#else
-#define is_isapnp_selected() 0
-#endif
#ifdef OPTi93X
#define CHIP_NAME "82C93x"
#else
@@ -2087,42 +2092,19 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
static int __init alsa_card_opti9xx_init(void)
{
- int error;
- struct platform_device *device;
-
#ifdef CONFIG_PNP
pnp_register_card_driver(&opti9xx_pnpc_driver);
if (snd_opti9xx_pnp_is_probed)
return 0;
#endif
- if (! is_isapnp_selected()) {
- error = platform_driver_register(&snd_opti9xx_driver);
- if (error < 0)
- return error;
- device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
- if (!IS_ERR(device)) {
- if (platform_get_drvdata(device)) {
- snd_opti9xx_platform_device = device;
- return 0;
- }
- platform_device_unregister(device);
- }
- platform_driver_unregister(&snd_opti9xx_driver);
- }
-#ifdef CONFIG_PNP
- pnp_unregister_card_driver(&opti9xx_pnpc_driver);
-#endif
-#ifdef MODULE
- printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n");
-#endif
- return -ENODEV;
+ return isa_register_driver(&snd_opti9xx_driver, 1);
}
static void __exit alsa_card_opti9xx_exit(void)
{
if (!snd_opti9xx_pnp_is_probed) {
- platform_device_unregister(snd_opti9xx_platform_device);
- platform_driver_unregister(&snd_opti9xx_driver);
+ isa_unregister_driver(&snd_opti9xx_driver);
+ return;
}
#ifdef CONFIG_PNP
pnp_unregister_card_driver(&opti9xx_pnpc_driver);
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index d64e67f2baf..2a19b0a39ed 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -25,7 +25,7 @@
#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/sb.h>
@@ -128,7 +128,6 @@ module_param_array(seq_ports, int, NULL, 0444);
MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
#endif
-static struct platform_device *platform_devices[SNDRV_CARDS];
#ifdef CONFIG_PNP
static int pnp_registered;
#endif
@@ -519,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card)
}
#endif
-static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev)
{
struct snd_card_sb16 *acard;
struct snd_card *card;
@@ -539,19 +538,23 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev
awe_port[dev] = port[dev] + 0x400;
#endif
- snd_card_set_dev(card, &devptr->dev);
+ snd_card_set_dev(card, pdev);
if ((err = snd_sb16_probe(card, dev)) < 0) {
snd_card_free(card);
return err;
}
- platform_set_drvdata(devptr, card);
+ dev_set_drvdata(pdev, card);
return 0;
}
-static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev)
+{
+ return enable[dev] && !is_isapnp_selected(dev);
+}
+
+static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
{
- int dev = pdev->id;
int err;
static int possible_irqs[] = {5, 9, 10, 7, -1};
static int possible_dmas8[] = {1, 3, 0, -1};
@@ -577,13 +580,13 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
}
if (port[dev] != SNDRV_AUTO_PORT)
- return snd_sb16_nonpnp_probe1(dev, pdev);
+ return snd_sb16_isa_probe1(dev, pdev);
else {
static int possible_ports[] = {0x220, 0x240, 0x260, 0x280};
int i;
for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
port[dev] = possible_ports[i];
- err = snd_sb16_nonpnp_probe1(dev, pdev);
+ err = snd_sb16_isa_probe1(dev, pdev);
if (! err)
return 0;
}
@@ -591,47 +594,47 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
}
}
-static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(pdev));
+ dev_set_drvdata(pdev, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_sb16_isa_suspend(struct device *dev, unsigned int n,
+ pm_message_t state)
{
- return snd_sb16_suspend(platform_get_drvdata(dev), state);
+ return snd_sb16_suspend(dev_get_drvdata(dev), state);
}
-static int snd_sb16_nonpnp_resume(struct platform_device *dev)
+static int snd_sb16_isa_resume(struct device *dev, unsigned int n)
{
- return snd_sb16_resume(platform_get_drvdata(dev));
+ return snd_sb16_resume(dev_get_drvdata(dev));
}
#endif
#ifdef SNDRV_SBAWE
-#define SND_SB16_DRIVER "snd_sbawe"
+#define DEV_NAME "sbawe"
#else
-#define SND_SB16_DRIVER "snd_sb16"
+#define DEV_NAME "sb16"
#endif
-static struct platform_driver snd_sb16_nonpnp_driver = {
- .probe = snd_sb16_nonpnp_probe,
- .remove = __devexit_p(snd_sb16_nonpnp_remove),
+static struct isa_driver snd_sb16_isa_driver = {
+ .match = snd_sb16_isa_match,
+ .probe = snd_sb16_isa_probe,
+ .remove = __devexit_p(snd_sb16_isa_remove),
#ifdef CONFIG_PM
- .suspend = snd_sb16_nonpnp_suspend,
- .resume = snd_sb16_nonpnp_resume,
+ .suspend = snd_sb16_isa_suspend,
+ .resume = snd_sb16_isa_resume,
#endif
.driver = {
- .name = SND_SB16_DRIVER
+ .name = DEV_NAME
},
};
#ifdef CONFIG_PNP
-static unsigned int __devinitdata sb16_pnp_devices;
-
static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
@@ -653,7 +656,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
}
pnp_set_card_drvdata(pcard, card);
dev++;
- sb16_pnp_devices++;
return 0;
}
@@ -695,68 +697,29 @@ static struct pnp_card_driver sb16_pnpc_driver = {
#endif /* CONFIG_PNP */
-static void __init_or_module snd_sb16_unregister_all(void)
-{
- int i;
-
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&sb16_pnpc_driver);
-#endif
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_sb16_nonpnp_driver);
-}
-
static int __init alsa_card_sb16_init(void)
{
- int i, err, cards = 0;
+ int err;
- if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0)
+ err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
+ if (err < 0)
return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i] || is_isapnp_selected(i))
- continue;
- device = platform_device_register_simple(SND_SB16_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- cards++;
- }
#ifdef CONFIG_PNP
/* PnP cards at last */
err = pnp_register_card_driver(&sb16_pnpc_driver);
- if (!err) {
+ if (!err)
pnp_registered = 1;
- cards += sb16_pnp_devices;
- }
-#endif
-
- if (!cards) {
-#ifdef MODULE
- snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");
-#ifdef SNDRV_SBAWE_EMU8000
- snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n");
-#else
- snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n");
#endif
-#endif
- snd_sb16_unregister_all();
- return -ENODEV;
- }
return 0;
}
static void __exit alsa_card_sb16_exit(void)
{
- snd_sb16_unregister_all();
+#ifdef CONFIG_PNP
+ if (pnp_registered)
+ pnp_unregister_card_driver(&sb16_pnpc_driver);
+#endif
+ isa_unregister_driver(&snd_sb16_isa_driver);
}
module_init(alsa_card_sb16_init)
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index 3d9d7e0107c..b279f2308ae 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -36,6 +36,13 @@
MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor");
MODULE_LICENSE("GPL");
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("sb16/mulaw_main.csp");
+MODULE_FIRMWARE("sb16/alaw_main.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_init.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
+#endif
#ifdef SNDRV_LITTLE_ENDIAN
#define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
@@ -161,13 +168,17 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
*/
static void snd_sb_csp_free(struct snd_hwdep *hwdep)
{
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
int i;
+#endif
struct snd_sb_csp *p = hwdep->private_data;
if (p) {
if (p->running & SNDRV_SB_CSP_ST_RUNNING)
snd_sb_csp_stop(p);
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i)
release_firmware(p->csp_programs[i]);
+#endif
kfree(p);
}
}
@@ -690,9 +701,7 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use
return err;
}
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
#include "sb16_csp_codecs.h"
static const struct firmware snd_sb_csp_static_programs[] = {
@@ -714,22 +723,19 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
"sb16/ima_adpcm_capture.csp",
};
const struct firmware *program;
- int err;
BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT);
program = p->csp_programs[index];
if (!program) {
- err = request_firmware(&program, names[index],
- p->chip->card->dev);
- if (err >= 0)
- p->csp_programs[index] = program;
- else {
-#ifdef FIRMWARE_IN_THE_KERNEL
- program = &snd_sb_csp_static_programs[index];
+#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
+ program = &snd_sb_csp_static_programs[index];
#else
+ int err = request_firmware(&program, names[index],
+ p->chip->card->dev);
+ if (err < 0)
return err;
#endif
- }
+ p->csp_programs[index] = program;
}
return snd_sb_csp_load(p, program->data, program->size, flags);
}
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index be1e83e6dea..a1b3786b391 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -22,7 +22,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/moduleparam.h>
@@ -56,8 +56,6 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
module_param_array(dma8, int, NULL, 0444);
MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
-static struct platform_device *devices[SNDRV_CARDS];
-
struct snd_sb8 {
struct resource *fm_res; /* used to block FM i/o region for legacy cards */
struct snd_sb *chip;
@@ -83,9 +81,23 @@ static void snd_sb8_free(struct snd_card *card)
release_and_free_resource(acard->fm_res);
}
-static int __devinit snd_sb8_probe(struct platform_device *pdev)
+static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev)
+{
+ if (!enable[dev])
+ return 0;
+ if (irq[dev] == SNDRV_AUTO_IRQ) {
+ snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
+ return 0;
+ }
+ if (dma8[dev] == SNDRV_AUTO_DMA) {
+ snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id);
+ return 0;
+ }
+ return 1;
+}
+
+static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
{
- int dev = pdev->id;
struct snd_sb *chip;
struct snd_card *card;
struct snd_sb8 *acard;
@@ -180,12 +192,12 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
chip->port,
irq[dev], dma8[dev]);
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, pdev);
if ((err = snd_card_register(card)) < 0)
goto _err;
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(pdev, card);
return 0;
_err:
@@ -193,17 +205,18 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
return err;
}
-static int __devexit snd_sb8_remove(struct platform_device *pdev)
+static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev)
{
- snd_card_free(platform_get_drvdata(pdev));
- platform_set_drvdata(pdev, NULL);
+ snd_card_free(dev_get_drvdata(pdev));
+ dev_set_drvdata(pdev, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_sb8_suspend(struct device *dev, unsigned int n,
+ pm_message_t state)
{
- struct snd_card *card = platform_get_drvdata(dev);
+ struct snd_card *card = dev_get_drvdata(dev);
struct snd_sb8 *acard = card->private_data;
struct snd_sb *chip = acard->chip;
@@ -213,9 +226,9 @@ static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
return 0;
}
-static int snd_sb8_resume(struct platform_device *dev)
+static int snd_sb8_resume(struct device *dev, unsigned int n)
{
- struct snd_card *card = platform_get_drvdata(dev);
+ struct snd_card *card = dev_get_drvdata(dev);
struct snd_sb8 *acard = card->private_data;
struct snd_sb *chip = acard->chip;
@@ -226,9 +239,10 @@ static int snd_sb8_resume(struct platform_device *dev)
}
#endif
-#define SND_SB8_DRIVER "snd_sb8"
+#define DEV_NAME "sb8"
-static struct platform_driver snd_sb8_driver = {
+static struct isa_driver snd_sb8_driver = {
+ .match = snd_sb8_match,
.probe = snd_sb8_probe,
.remove = __devexit_p(snd_sb8_remove),
#ifdef CONFIG_PM
@@ -236,56 +250,18 @@ static struct platform_driver snd_sb8_driver = {
.resume = snd_sb8_resume,
#endif
.driver = {
- .name = SND_SB8_DRIVER
+ .name = DEV_NAME
},
};
-static void __init_or_module snd_sb8_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_sb8_driver);
-}
-
static int __init alsa_card_sb8_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_sb8_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_SB8_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n");
-#endif
- snd_sb8_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS);
}
static void __exit alsa_card_sb8_exit(void)
{
- snd_sb8_unregister_all();
+ isa_unregister_driver(&snd_sb8_driver);
}
module_init(alsa_card_sb8_init)
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
index 4fcd0f4e868..922519def09 100644
--- a/sound/isa/sgalaxy.c
+++ b/sound/isa/sgalaxy.c
@@ -24,7 +24,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/interrupt.h>
@@ -64,8 +64,6 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
module_param_array(dma1, int, NULL, 0444);
MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
-static struct platform_device *devices[SNDRV_CARDS];
-
#define SGALAXY_AUXC_LEFT 18
#define SGALAXY_AUXC_RIGHT 19
@@ -96,7 +94,8 @@ static int snd_sgalaxy_sbdsp_reset(unsigned long port)
return 0;
}
-static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val)
+static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port,
+ unsigned char val)
{
int i;
@@ -114,7 +113,7 @@ static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
-static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
+static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
{
static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1,
0x10, 0x18, 0x20, -1, -1, -1, -1};
@@ -161,7 +160,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
return 0;
}
-static int __init snd_sgalaxy_detect(int dev, int irq, int dma)
+static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
{
#if 0
snd_printdd(PFX "switching to WSS mode\n");
@@ -182,7 +181,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7
AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
};
-static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
+static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip)
{
struct snd_card *card = chip->card;
struct snd_ctl_elem_id id1, id2;
@@ -218,23 +217,29 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
return 0;
}
-static int __init snd_sgalaxy_probe(struct platform_device *devptr)
+static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev)
{
- int dev = devptr->id;
- static int possible_irqs[] = {7, 9, 10, 11, -1};
- static int possible_dmas[] = {1, 3, 0, -1};
- int err, xirq, xdma1;
- struct snd_card *card;
- struct snd_ad1848 *chip;
-
+ if (!enable[dev])
+ return 0;
if (sbport[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify SB port\n");
- return -EINVAL;
+ return 0;
}
if (wssport[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR PFX "specify WSS port\n");
- return -EINVAL;
+ return 0;
}
+ return 1;
+}
+
+static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
+{
+ static int possible_irqs[] = {7, 9, 10, 11, -1};
+ static int possible_dmas[] = {1, 3, 0, -1};
+ int err, xirq, xdma1;
+ struct snd_card *card;
+ struct snd_ad1848 *chip;
+
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -283,12 +288,12 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
wssport[dev], xirq, xdma1);
- snd_card_set_dev(card, &devptr->dev);
+ snd_card_set_dev(card, devptr);
if ((err = snd_card_register(card)) < 0)
goto _err;
- platform_set_drvdata(devptr, card);
+ dev_set_drvdata(devptr, card);
return 0;
_err:
@@ -296,17 +301,18 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
return err;
}
-static int __devexit snd_sgalaxy_remove(struct platform_device *devptr)
+static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
#ifdef CONFIG_PM
-static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
+static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
+ pm_message_t state)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(pdev);
struct snd_ad1848 *chip = card->private_data;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -314,9 +320,9 @@ static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int snd_sgalaxy_resume(struct platform_device *pdev)
+static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
{
- struct snd_card *card = platform_get_drvdata(pdev);
+ struct snd_card *card = dev_get_drvdata(pdev);
struct snd_ad1848 *chip = card->private_data;
chip->resume(chip);
@@ -328,9 +334,10 @@ static int snd_sgalaxy_resume(struct platform_device *pdev)
}
#endif
-#define SND_SGALAXY_DRIVER "snd_sgalaxy"
+#define DEV_NAME "sgalaxy"
-static struct platform_driver snd_sgalaxy_driver = {
+static struct isa_driver snd_sgalaxy_driver = {
+ .match = snd_sgalaxy_match,
.probe = snd_sgalaxy_probe,
.remove = __devexit_p(snd_sgalaxy_remove),
#ifdef CONFIG_PM
@@ -338,56 +345,18 @@ static struct platform_driver snd_sgalaxy_driver = {
.resume = snd_sgalaxy_resume,
#endif
.driver = {
- .name = SND_SGALAXY_DRIVER
+ .name = DEV_NAME
},
};
-static void __init_or_module snd_sgalaxy_unregister_all(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(devices); ++i)
- platform_device_unregister(devices[i]);
- platform_driver_unregister(&snd_sgalaxy_driver);
-}
-
static int __init alsa_card_sgalaxy_init(void)
{
- int i, cards, err;
-
- err = platform_driver_register(&snd_sgalaxy_driver);
- if (err < 0)
- return err;
-
- cards = 0;
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
- device = platform_device_register_simple(SND_SGALAXY_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- devices[i] = device;
- cards++;
- }
- if (!cards) {
-#ifdef MODULE
- snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n");
-#endif
- snd_sgalaxy_unregister_all();
- return -ENODEV;
- }
- return 0;
+ return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS);
}
static void __exit alsa_card_sgalaxy_exit(void)
{
- snd_sgalaxy_unregister_all();
+ isa_unregister_driver(&snd_sgalaxy_driver);
}
module_init(alsa_card_sgalaxy_init)
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index b1f25823c65..08c14978558 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -24,7 +24,7 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/pnp.h>
#include <linux/spinlock.h>
@@ -68,8 +68,6 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
module_param_array(dma, int, NULL, 0444);
MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
-static struct platform_device *platform_devices[SNDRV_CARDS];
-
#ifdef CONFIG_PNP
static int pnp_registered;
static struct pnp_card_device_id sscape_pnpids[] = {
@@ -1254,9 +1252,27 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
}
-static int __devinit snd_sscape_probe(struct platform_device *pdev)
+static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
+{
+ /*
+ * Make sure we were given ALL of the other parameters.
+ */
+ if (port[i] == SNDRV_AUTO_PORT)
+ return 0;
+
+ if (irq[i] == SNDRV_AUTO_IRQ ||
+ mpu_irq[i] == SNDRV_AUTO_IRQ ||
+ dma[i] == SNDRV_AUTO_DMA) {
+ printk(KERN_INFO
+ "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
{
- int dev = pdev->id;
struct snd_card *card;
int ret;
@@ -1264,30 +1280,31 @@ static int __devinit snd_sscape_probe(struct platform_device *pdev)
ret = create_sscape(dev, &card);
if (ret < 0)
return ret;
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, pdev);
if ((ret = snd_card_register(card)) < 0) {
printk(KERN_ERR "sscape: Failed to register sound card\n");
return ret;
}
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(pdev, card);
return 0;
}
-static int __devexit snd_sscape_remove(struct platform_device *devptr)
+static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
-#define SSCAPE_DRIVER "snd_sscape"
+#define DEV_NAME "sscape"
-static struct platform_driver snd_sscape_driver = {
+static struct isa_driver snd_sscape_driver = {
+ .match = snd_sscape_match,
.probe = snd_sscape_probe,
.remove = __devexit_p(snd_sscape_remove),
/* FIXME: suspend/resume */
.driver = {
- .name = SSCAPE_DRIVER
+ .name = DEV_NAME
},
};
@@ -1386,72 +1403,6 @@ static struct pnp_card_driver sscape_pnpc_driver = {
#endif /* CONFIG_PNP */
-static void __init_or_module sscape_unregister_all(void)
-{
- int i;
-
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&sscape_pnpc_driver);
-#endif
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_sscape_driver);
-}
-
-static int __init sscape_manual_probe(void)
-{
- struct platform_device *device;
- int i, ret;
-
- ret = platform_driver_register(&snd_sscape_driver);
- if (ret < 0)
- return ret;
-
- for (i = 0; i < SNDRV_CARDS; ++i) {
- /*
- * We do NOT probe for ports.
- * If we're not given a port number for this
- * card then we completely ignore this line
- * of parameters.
- */
- if (port[i] == SNDRV_AUTO_PORT)
- continue;
-
- /*
- * Make sure we were given ALL of the other parameters.
- */
- if (irq[i] == SNDRV_AUTO_IRQ ||
- mpu_irq[i] == SNDRV_AUTO_IRQ ||
- dma[i] == SNDRV_AUTO_DMA) {
- printk(KERN_INFO
- "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
- sscape_unregister_all();
- return -ENXIO;
- }
-
- /*
- * This cards looks OK ...
- */
- device = platform_device_register_simple(SSCAPE_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- }
- return 0;
-}
-
-static void sscape_exit(void)
-{
- sscape_unregister_all();
-}
-
-
static int __init sscape_init(void)
{
int ret;
@@ -1462,7 +1413,7 @@ static int __init sscape_init(void)
* of allocating cards, because the operator is
* S-P-E-L-L-I-N-G it out for us...
*/
- ret = sscape_manual_probe();
+ ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
if (ret < 0)
return ret;
#ifdef CONFIG_PNP
@@ -1472,5 +1423,14 @@ static int __init sscape_init(void)
return 0;
}
+static void __exit sscape_exit(void)
+{
+#ifdef CONFIG_PNP
+ if (pnp_registered)
+ pnp_unregister_card_driver(&sscape_pnpc_driver);
+#endif
+ isa_unregister_driver(&snd_sscape_driver);
+}
+
module_init(sscape_init);
module_exit(sscape_exit);
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index e2fdd5fd39d..75673f72385 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -24,7 +24,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
@@ -40,7 +40,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+#ifdef CONFIG_PNP
static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+#endif
static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
@@ -83,8 +85,6 @@ MODULE_PARM_DESC(fm_port, "FM port #.");
module_param_array(use_cs4232_midi, bool, NULL, 0444);
MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
-static struct platform_device *platform_devices[SNDRV_CARDS];
-
#ifdef CONFIG_PNP
static int pnp_registered;
@@ -588,56 +588,67 @@ snd_wavefront_probe (struct snd_card *card, int dev)
return snd_card_register(card);
}
-static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_wavefront_isa_match(struct device *pdev,
+ unsigned int dev)
{
- int dev = pdev->id;
- struct snd_card *card;
- int err;
-
+ if (!enable[dev])
+ return 0;
+#ifdef CONFIG_PNP
+ if (isapnp[dev])
+ return 0;
+#endif
if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
snd_printk("specify CS4232 port\n");
- return -EINVAL;
+ return 0;
}
if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
snd_printk("specify ICS2115 port\n");
- return -ENODEV;
+ return 0;
}
+ return 1;
+}
+
+static int __devinit snd_wavefront_isa_probe(struct device *pdev,
+ unsigned int dev)
+{
+ struct snd_card *card;
+ int err;
card = snd_wavefront_card_new(dev);
if (! card)
return -ENOMEM;
- snd_card_set_dev(card, &pdev->dev);
+ snd_card_set_dev(card, pdev);
if ((err = snd_wavefront_probe(card, dev)) < 0) {
snd_card_free(card);
return err;
}
- platform_set_drvdata(pdev, card);
+ dev_set_drvdata(pdev, card);
return 0;
}
-static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_wavefront_isa_remove(struct device *devptr,
+ unsigned int dev)
{
- snd_card_free(platform_get_drvdata(devptr));
- platform_set_drvdata(devptr, NULL);
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
return 0;
}
-#define WAVEFRONT_DRIVER "snd_wavefront"
+#define DEV_NAME "wavefront"
-static struct platform_driver snd_wavefront_driver = {
- .probe = snd_wavefront_nonpnp_probe,
- .remove = __devexit_p(snd_wavefront_nonpnp_remove),
+static struct isa_driver snd_wavefront_driver = {
+ .match = snd_wavefront_isa_match,
+ .probe = snd_wavefront_isa_probe,
+ .remove = __devexit_p(snd_wavefront_isa_remove),
/* FIXME: suspend, resume */
.driver = {
- .name = WAVEFRONT_DRIVER
+ .name = DEV_NAME
},
};
#ifdef CONFIG_PNP
-static unsigned int __devinitdata wavefront_pnp_devices;
-
static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
@@ -670,7 +681,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
pnp_set_card_drvdata(pcard, card);
dev++;
- wavefront_pnp_devices++;
return 0;
}
@@ -691,67 +701,28 @@ static struct pnp_card_driver wavefront_pnpc_driver = {
#endif /* CONFIG_PNP */
-static void __init_or_module snd_wavefront_unregister_all(void)
-{
- int i;
-
-#ifdef CONFIG_PNP
- if (pnp_registered)
- pnp_unregister_card_driver(&wavefront_pnpc_driver);
-#endif
- for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
- platform_device_unregister(platform_devices[i]);
- platform_driver_unregister(&snd_wavefront_driver);
-}
-
static int __init alsa_card_wavefront_init(void)
{
- int i, err, cards = 0;
+ int err;
- if ((err = platform_driver_register(&snd_wavefront_driver)) < 0)
+ err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
+ if (err < 0)
return err;
-
- for (i = 0; i < SNDRV_CARDS; i++) {
- struct platform_device *device;
- if (! enable[i])
- continue;
-#ifdef CONFIG_PNP
- if (isapnp[i])
- continue;
-#endif
- device = platform_device_register_simple(WAVEFRONT_DRIVER,
- i, NULL, 0);
- if (IS_ERR(device))
- continue;
- if (!platform_get_drvdata(device)) {
- platform_device_unregister(device);
- continue;
- }
- platform_devices[i] = device;
- cards++;
- }
-
#ifdef CONFIG_PNP
err = pnp_register_card_driver(&wavefront_pnpc_driver);
- if (!err) {
+ if (!err)
pnp_registered = 1;
- cards += wavefront_pnp_devices;
- }
-#endif
-
- if (!cards) {
-#ifdef MODULE
- printk (KERN_ERR "No WaveFront cards found or devices busy\n");
#endif
- snd_wavefront_unregister_all();
- return -ENODEV;
- }
return 0;
}
static void __exit alsa_card_wavefront_exit(void)
{
- snd_wavefront_unregister_all();
+#ifdef CONFIG_PNP
+ if (pnp_registered)
+ pnp_unregister_card_driver(&wavefront_pnpc_driver);
+#endif
+ isa_unregister_driver(&snd_wavefront_driver);
}
module_init(alsa_card_wavefront_init)
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
index 15331ed8819..fc95a870f69 100644
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -35,9 +35,7 @@
#define WAIT_IDLE 0xff
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
#include "yss225.c"
static const struct firmware yss225_registers_firmware = {
.data = (u8 *)yss225_registers,
@@ -258,21 +256,21 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
{
unsigned int i;
int err;
- const struct firmware *firmware;
+ const struct firmware *firmware = NULL;
if (dev->fx_initialized)
return 0;
+#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+ firmware = &yss225_registers_firmware;
+#else
err = request_firmware(&firmware, "yamaha/yss225_registers.bin",
dev->card->dev);
if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
- firmware = &yss225_registers_firmware;
-#else
err = -1;
goto out;
-#endif
}
+#endif
for (i = 0; i + 1 < firmware->size; i += 2) {
if (firmware->data[i] >= 8 && firmware->data[i] < 16) {
@@ -295,9 +293,12 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
err = 0;
out:
-#ifdef FIRMWARE_IN_THE_KERNEL
- if (firmware != &yss225_registers_firmware)
+#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+ release_firmware(firmware);
#endif
- release_firmware(firmware);
return err;
}
+
+#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("yamaha/yss225_registers.bin");
+#endif
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 1bcfb3aac18..61e35ecc57b 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -576,7 +576,7 @@ config SND_INTEL8X0M
config SND_KORG1212
tristate "Korg 1212 IO"
depends on SND
- select FW_LOADER
+ select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL
select SND_PCM
help
Say Y here to include support for Korg 1212IO soundcards.
@@ -584,10 +584,19 @@ config SND_KORG1212
To compile this driver as a module, choose M here: the module
will be called snd-korg1212.
+config SND_KORG1212_FIRMWARE_IN_KERNEL
+ bool "In-kernel firmware for Korg1212 driver"
+ depends on SND_KORG1212
+ default y
+ help
+ Say Y here to include the static firmware built in the kernel
+ for the Korg1212 driver. If you choose N here, you need to
+ install the firmware files from the alsa-firmware package.
+
config SND_MAESTRO3
tristate "ESS Allegro/Maestro3"
depends on SND
- select FW_LOADER
+ select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL
select SND_AC97_CODEC
help
Say Y here to include support for soundcards based on ESS Maestro 3
@@ -596,6 +605,15 @@ config SND_MAESTRO3
To compile this driver as a module, choose M here: the module
will be called snd-maestro3.
+config SND_MAESTRO3_FIRMWARE_IN_KERNEL
+ bool "In-kernel firmware for Maestro3 driver"
+ depends on SND_MAESTRO3
+ default y
+ help
+ Say Y here to include the static firmware built in the kernel
+ for the Maestro3 driver. If you choose N here, you need to
+ install the firmware files from the alsa-firmware package.
+
config SND_MIXART
tristate "Digigram miXart"
depends on SND
@@ -737,7 +755,7 @@ config SND_VX222
config SND_YMFPCI
tristate "Yamaha YMF724/740/744/754"
depends on SND
- select FW_LOADER
+ select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_AC97_CODEC
@@ -748,6 +766,15 @@ config SND_YMFPCI
To compile this driver as a module, choose M here: the module
will be called snd-ymfpci.
+config SND_YMFPCI_FIRMWARE_IN_KERNEL
+ bool "In-kernel firmware for YMFPCI driver"
+ depends on SND_YMFPCI
+ default y
+ help
+ Say Y here to include the static firmware built in the kernel
+ for the YMFPCI driver. If you choose N here, you need to
+ install the firmware files from the alsa-firmware package.
+
config SND_AC97_POWER_SAVE
bool "AC97 Power-Saving Mode"
depends on SND_AC97_CODEC && EXPERIMENTAL
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile
index 3c3222122d8..f5d471896b9 100644
--- a/sound/pci/ac97/Makefile
+++ b/sound/pci/ac97/Makefile
@@ -3,7 +3,7 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
#
-snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o
+snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o
ifneq ($(CONFIG_PROC_FS),)
snd-ac97-codec-objs += ac97_proc.o
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 3bfb2102fc5..bbed644bf9c 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -35,9 +35,9 @@
#include <sound/ac97_codec.h>
#include <sound/asoundef.h>
#include <sound/initval.h>
-#include "ac97_local.h"
#include "ac97_id.h"
-#include "ac97_patch.h"
+
+#include "ac97_patch.c"
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
@@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns
* Controls
*/
-int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
@@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
return 0;
}
-int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
@@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
return 0;
}
-int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
@@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save)
}
/* volume and switch controls */
-int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
int mask = (kcontrol->private_value >> 16) & 0xff;
int shift = (kcontrol->private_value >> 8) & 0x0f;
@@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
return 0;
}
-int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
@@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
return 0;
}
-int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
@@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]),
AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
};
-const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0),
AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0)
};
@@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
return change;
}
-const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
+static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha
}
}
-int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
+static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
{
unsigned short mask, val, orig, res;
@@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x)
return x;
}
-struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97)
+static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
+ struct snd_ac97 * ac97)
{
struct snd_kcontrol_new template;
memcpy(&template, _template, sizeof(template));
@@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix)
}
/* remove the control with the given name and optional suffix */
-int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix)
+static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+ const char *suffix)
{
struct snd_ctl_elem_id id;
memset(&id, 0, sizeof(id));
@@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co
}
/* rename the control with the given name and optional suffix */
-int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix)
+static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+ const char *dst, const char *suffix)
{
struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
if (kctl) {
@@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst,
}
/* rename both Volume and Switch controls - don't check the return value */
-void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst)
+static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
+ const char *dst)
{
snd_ac97_rename_ctl(ac97, src, dst, "Switch");
snd_ac97_rename_ctl(ac97, src, dst, "Volume");
}
/* swap controls */
-int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix)
+static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+ const char *s2, const char *suffix)
{
struct snd_kcontrol *kctl1, *kctl2;
kctl1 = ctl_find(ac97, s1, suffix);
diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
index a6244c720a1..78745c5c6df 100644
--- a/sound/pci/ac97/ac97_local.h
+++ b/sound/pci/ac97/ac97_local.h
@@ -22,59 +22,8 @@
*
*/
-#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24))
-#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
-#define AC97_SINGLE(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
- .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
- .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) }
-#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
- .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
- .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
-#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \
- .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
- .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
-
-/* enum control */
-struct ac97_enum {
- unsigned char reg;
- unsigned char shift_l;
- unsigned char shift_r;
- unsigned short mask;
- const char **texts;
-};
-
-#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
-{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
- .mask = xmask, .texts = xtexts }
-#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
- AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
-#define AC97_ENUM(xname, xenum) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \
- .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
- .private_value = (unsigned long)&xenum }
-
-/* ac97_codec.c */
-extern const struct snd_kcontrol_new snd_ac97_controls_3d[];
-extern const struct snd_kcontrol_new snd_ac97_controls_spdif[];
-struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97);
-void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem);
-int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
-int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix);
-int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix);
-int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix);
-void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst);
-void snd_ac97_restore_status(struct snd_ac97 *ac97);
-void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
-int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-
+void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name,
+ int modem);
int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
unsigned short mask, unsigned short value);
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index b188a4df58c..3eac0f86266 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -23,20 +23,8 @@
*
*/
-#include <sound/driver.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/ac97_codec.h>
-#include "ac97_patch.h"
-#include "ac97_id.h"
#include "ac97_local.h"
+#include "ac97_patch.h"
/*
* Chip specific initialization
@@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
.build_post_spdif = patch_yamaha_ymf753_post_spdif
};
-int patch_yamaha_ymf753(struct snd_ac97 * ac97)
+static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
{
/* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
@@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
.build_specific = patch_wolfson_wm9703_specific,
};
-int patch_wolfson03(struct snd_ac97 * ac97)
+static int patch_wolfson03(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_wolfson_wm9703_ops;
return 0;
@@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
.build_specific = patch_wolfson_wm9704_specific,
};
-int patch_wolfson04(struct snd_ac97 * ac97)
+static int patch_wolfson04(struct snd_ac97 * ac97)
{
/* WM9704M/9704Q */
ac97->build_ops = &patch_wolfson_wm9704_ops;
@@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
.build_specific = patch_wolfson_wm9705_specific,
};
-int patch_wolfson05(struct snd_ac97 * ac97)
+static int patch_wolfson05(struct snd_ac97 * ac97)
{
/* WM9705, WM9710 */
ac97->build_ops = &patch_wolfson_wm9705_ops;
@@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
.build_specific = patch_wolfson_wm9711_specific,
};
-int patch_wolfson11(struct snd_ac97 * ac97)
+static int patch_wolfson11(struct snd_ac97 * ac97)
{
/* WM9711, WM9712 */
ac97->build_ops = &patch_wolfson_wm9711_ops;
@@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
#endif
};
-int patch_wolfson13(struct snd_ac97 * ac97)
+static int patch_wolfson13(struct snd_ac97 * ac97)
{
/* WM9713, WM9714 */
ac97->build_ops = &patch_wolfson_wm9713_ops;
@@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97)
/*
* Tritech codec
*/
-int patch_tritech_tr28028(struct snd_ac97 * ac97)
+static int patch_tritech_tr28028(struct snd_ac97 * ac97)
{
snd_ac97_write_cache(ac97, 0x26, 0x0300);
snd_ac97_write_cache(ac97, 0x26, 0x0000);
@@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
.build_specific = patch_sigmatel_stac97xx_specific
};
-int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_sigmatel_stac9700_ops;
return 0;
@@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
.build_specific = patch_sigmatel_stac9708_specific
};
-int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
{
unsigned int codec72, codec6c;
@@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
return 0;
}
-int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_sigmatel_stac9700_ops;
if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
@@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
return 0;
}
-int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
{
// patch for SigmaTel
ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
return 0;
}
-int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
{
// patch for SigmaTel
ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
.build_specific = patch_sigmatel_stac9758_specific
};
-int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
{
static unsigned short regs[4] = {
AC97_SIGMATEL_OUTSEL,
@@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = {
.build_spdif = patch_cirrus_build_spdif
};
-int patch_cirrus_spdif(struct snd_ac97 * ac97)
+static int patch_cirrus_spdif(struct snd_ac97 * ac97)
{
/* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh*
@@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97)
return 0;
}
-int patch_cirrus_cs4299(struct snd_ac97 * ac97)
+static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
{
/* force the detection of PC Beep */
ac97->flags |= AC97_HAS_PC_BEEP;
@@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = {
.build_spdif = patch_conexant_build_spdif
};
-int patch_conexant(struct snd_ac97 * ac97)
+static int patch_conexant(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_conexant_ops;
ac97->flags |= AC97_CX_SPDIF;
@@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97)
return 0;
}
-int patch_cx20551(struct snd_ac97 *ac97)
+static int patch_cx20551(struct snd_ac97 *ac97)
{
snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
return 0;
@@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = {
{ } /* terminator */
};
-int patch_ad1819(struct snd_ac97 * ac97)
+static int patch_ad1819(struct snd_ac97 * ac97)
{
unsigned short scfg;
@@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = {
#endif
};
-int patch_ad1881(struct snd_ac97 * ac97)
+static int patch_ad1881(struct snd_ac97 * ac97)
{
static const char cfg_idxs[3][2] = {
{2, 1},
@@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = {
#endif
};
-int patch_ad1885(struct snd_ac97 * ac97)
+static int patch_ad1885(struct snd_ac97 * ac97)
{
patch_ad1881(ac97);
/* This is required to deal with the Intel D815EEAL2 */
@@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = {
#endif
};
-int patch_ad1886(struct snd_ac97 * ac97)
+static int patch_ad1886(struct snd_ac97 * ac97)
{
patch_ad1881(ac97);
/* Presario700 workaround */
@@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
}
-int patch_ad1981a(struct snd_ac97 *ac97)
+static int patch_ad1981a(struct snd_ac97 *ac97)
{
patch_ad1881(ac97);
ac97->build_ops = &patch_ad1981a_build_ops;
@@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
#endif
};
-int patch_ad1981b(struct snd_ac97 *ac97)
+static int patch_ad1981b(struct snd_ac97 *ac97)
{
patch_ad1881(ac97);
ac97->build_ops = &patch_ad1981b_build_ops;
@@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
.update_jacks = ad1888_update_jacks,
};
-int patch_ad1888(struct snd_ac97 * ac97)
+static int patch_ad1888(struct snd_ac97 * ac97)
{
unsigned short misc;
@@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = {
.update_jacks = ad1888_update_jacks,
};
-int patch_ad1980(struct snd_ac97 * ac97)
+static int patch_ad1980(struct snd_ac97 * ac97)
{
patch_ad1888(ac97);
ac97->build_ops = &patch_ad1980_build_ops;
@@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = {
.update_jacks = ad1985_update_jacks,
};
-int patch_ad1985(struct snd_ac97 * ac97)
+static int patch_ad1985(struct snd_ac97 * ac97)
{
unsigned short misc;
@@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = {
.update_jacks = ad1986_update_jacks,
};
-int patch_ad1986(struct snd_ac97 * ac97)
+static int patch_ad1986(struct snd_ac97 * ac97)
{
patch_ad1881(ac97);
ac97->build_ops = &patch_ad1986_build_ops;
@@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = {
.update_jacks = alc650_update_jacks
};
-int patch_alc650(struct snd_ac97 * ac97)
+static int patch_alc650(struct snd_ac97 * ac97)
{
unsigned short val;
@@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = {
.update_jacks = alc655_update_jacks
};
-int patch_alc655(struct snd_ac97 * ac97)
+static int patch_alc655(struct snd_ac97 * ac97)
{
unsigned int val;
@@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97)
(ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
ac97->subsystem_device == 0x0161 || /* LG K1 Express */
ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
+ ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */
ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */
val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
else
@@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = {
.update_jacks = alc850_update_jacks
};
-int patch_alc850(struct snd_ac97 *ac97)
+static int patch_alc850(struct snd_ac97 *ac97)
{
ac97->build_ops = &patch_alc850_ops;
@@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = {
.update_jacks = cm9738_update_jacks
};
-int patch_cm9738(struct snd_ac97 * ac97)
+static int patch_cm9738(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_cm9738_ops;
/* FIXME: can anyone confirm below? */
@@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = {
.update_jacks = cm9739_update_jacks
};
-int patch_cm9739(struct snd_ac97 * ac97)
+static int patch_cm9739(struct snd_ac97 * ac97)
{
unsigned short val;
@@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = {
.update_jacks = cm9761_update_jacks
};
-int patch_cm9761(struct snd_ac97 *ac97)
+static int patch_cm9761(struct snd_ac97 *ac97)
{
unsigned short val;
@@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = {
.build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
};
-int patch_cm9780(struct snd_ac97 *ac97)
+static int patch_cm9780(struct snd_ac97 *ac97)
{
unsigned short val;
@@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = {
.build_specific = patch_vt1616_specific
};
-int patch_vt1616(struct snd_ac97 * ac97)
+static int patch_vt1616(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_vt1616_ops;
return 0;
@@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97)
/*
* VT1617A codec
*/
+
+/*
+ * unfortunately, the vt1617a stashes the twiddlers required for
+ * nooding the i/o jacks on 2 different regs. * thameans that we cant
+ * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
+ * are own funcs.
+ *
+ * NB: this is absolutely and utterly different from the vt1618. dunno
+ * about the 1616.
+ */
+
+/* copied from ac97_surround_jack_mode_info() */
+static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ /* ordering in this list reflects vt1617a docs for Reg 20 and
+ * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
+ * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
+ * counter-intuitive */
+
+ static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
+ "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
+ "LineIn Mic2", "LineIn Mic2 Mic1",
+ "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
+ return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
+}
+
+static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ushort usSM51, usMS;
+
+ struct snd_ac97 *pac97;
+
+ pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
+
+ /* grab our desirec bits, then mash them together in a manner
+ * consistent with Table 6 on page 17 in the 1617a docs */
+
+ usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
+ usMS = snd_ac97_read(pac97, 0x20) >> 8;
+
+ ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
+
+ return 0;
+}
+
+static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ushort usSM51, usMS, usReg;
+
+ struct snd_ac97 *pac97;
+
+ pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
+
+ usSM51 = ucontrol->value.enumerated.item[0] >> 1;
+ usMS = ucontrol->value.enumerated.item[0] & 1;
+
+ /* push our values into the register - consider that things will be left
+ * in a funky state if the write fails */
+
+ usReg = snd_ac97_read(pac97, 0x7a);
+ snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
+ usReg = snd_ac97_read(pac97, 0x20);
+ snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8));
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
+
+ AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
+ /*
+ * These are used to enable/disable surround sound on motherboards
+ * that have 3 bidirectional analog jacks
+ */
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Smart 5.1 Select",
+ .info = snd_ac97_vt1617a_smart51_info,
+ .get = snd_ac97_vt1617a_smart51_get,
+ .put = snd_ac97_vt1617a_smart51_put,
+ },
+};
+
int patch_vt1617a(struct snd_ac97 * ac97)
{
- /* bring analog power consumption to normal, like WinXP driver
- * for EPIA SP
+ int err = 0;
+
+ /* we choose to not fail out at this point, but we tell the
+ caller when we return */
+
+ err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
+ ARRAY_SIZE(snd_ac97_controls_vt1617a));
+
+ /* bring analog power consumption to normal by turning off the
+ * headphone amplifier, like WinXP driver for EPIA SP
*/
snd_ac97_write_cache(ac97, 0x5c, 0x20);
ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
ac97->build_ops = &patch_vt1616_ops;
- return 0;
+
+ return err;
}
/*
@@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = {
.update_jacks = it2646_update_jacks
};
-int patch_it2646(struct snd_ac97 * ac97)
+static int patch_it2646(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_it2646_ops;
/* full DAC volume */
@@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = {
.build_specific = patch_si3036_specific,
};
-int mpatch_si3036(struct snd_ac97 * ac97)
+static int mpatch_si3036(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_si3036_ops;
snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
@@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = {
{ } /* terminator */
};
-int patch_lm4550(struct snd_ac97 *ac97)
+static int patch_lm4550(struct snd_ac97 *ac97)
{
ac97->res_table = lm4550_restbl;
return 0;
@@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = {
.build_specific = patch_ucb1400_specific,
};
-int patch_ucb1400(struct snd_ac97 * ac97)
+static int patch_ucb1400(struct snd_ac97 * ac97)
{
ac97->build_ops = &patch_ucb1400_ops;
/* enable headphone driver and smart low power mode by default */
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
index 555d1c9a98f..fd341ce6376 100644
--- a/sound/pci/ac97/ac97_patch.h
+++ b/sound/pci/ac97/ac97_patch.h
@@ -22,44 +22,72 @@
*
*/
-int patch_yamaha_ymf753(struct snd_ac97 * ac97);
-int patch_wolfson00(struct snd_ac97 * ac97);
-int patch_wolfson03(struct snd_ac97 * ac97);
-int patch_wolfson04(struct snd_ac97 * ac97);
-int patch_wolfson05(struct snd_ac97 * ac97);
-int patch_wolfson11(struct snd_ac97 * ac97);
-int patch_wolfson13(struct snd_ac97 * ac97);
-int patch_tritech_tr28028(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9700(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9708(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9721(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9744(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9756(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9758(struct snd_ac97 * ac97);
-int patch_cirrus_cs4299(struct snd_ac97 * ac97);
-int patch_cirrus_spdif(struct snd_ac97 * ac97);
-int patch_conexant(struct snd_ac97 * ac97);
-int patch_cx20551(struct snd_ac97 * ac97);
-int patch_ad1819(struct snd_ac97 * ac97);
-int patch_ad1881(struct snd_ac97 * ac97);
-int patch_ad1885(struct snd_ac97 * ac97);
-int patch_ad1886(struct snd_ac97 * ac97);
-int patch_ad1888(struct snd_ac97 * ac97);
-int patch_ad1980(struct snd_ac97 * ac97);
-int patch_ad1981a(struct snd_ac97 * ac97);
-int patch_ad1981b(struct snd_ac97 * ac97);
-int patch_ad1985(struct snd_ac97 * ac97);
-int patch_ad1986(struct snd_ac97 * ac97);
-int patch_alc650(struct snd_ac97 * ac97);
-int patch_alc655(struct snd_ac97 * ac97);
-int patch_alc850(struct snd_ac97 * ac97);
-int patch_cm9738(struct snd_ac97 * ac97);
-int patch_cm9739(struct snd_ac97 * ac97);
-int patch_cm9761(struct snd_ac97 * ac97);
-int patch_cm9780(struct snd_ac97 * ac97);
-int patch_vt1616(struct snd_ac97 * ac97);
-int patch_vt1617a(struct snd_ac97 * ac97);
-int patch_it2646(struct snd_ac97 * ac97);
-int patch_ucb1400(struct snd_ac97 * ac97);
-int mpatch_si3036(struct snd_ac97 * ac97);
-int patch_lm4550(struct snd_ac97 * ac97);
+#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \
+ ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \
+ ((invert) << 24))
+#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \
+ (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
+#define AC97_SINGLE(xname, reg, shift, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_ac97_info_volsw, \
+ .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+ .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) }
+#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_ac97_info_volsw, \
+ .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+ .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
+#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+ .info = snd_ac97_info_volsw, \
+ .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+ .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
+
+/* enum control */
+struct ac97_enum {
+ unsigned char reg;
+ unsigned char shift_l;
+ unsigned char shift_r;
+ unsigned short mask;
+ const char **texts;
+};
+
+#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
+{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
+ .mask = xmask, .texts = xtexts }
+#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
+ AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
+#define AC97_ENUM(xname, xenum) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .info = snd_ac97_info_enum_double, \
+ .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
+ .private_value = (unsigned long)&xenum }
+
+/* ac97_codec.c */
+static const struct snd_kcontrol_new snd_ac97_controls_3d[];
+static const struct snd_kcontrol_new snd_ac97_controls_spdif[];
+static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
+ struct snd_ac97 * ac97);
+static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
+static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+ const char *suffix);
+static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+ const char *dst, const char *suffix);
+static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+ const char *s2, const char *suffix);
+static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
+ const char *dst);
+static void snd_ac97_restore_status(struct snd_ac97 *ac97);
+static void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
+static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index 3758d07182f..4281e6d0c5b 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -34,7 +34,6 @@
#include <sound/control.h>
#include <sound/ac97_codec.h>
#include <sound/asoundef.h>
-#include "ac97_patch.h"
#include "ac97_id.h"
#include "ac97_local.h"
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index ba7fa22b285..e1ed59549c5 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -69,10 +69,10 @@ module_param(enable, bool, 0444);
* Debug part definitions
*/
-//#define ALI_DEBUG
+/* #define ALI_DEBUG */
#ifdef ALI_DEBUG
-#define snd_ali_printk(format, args...) printk(format, ##args);
+#define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args);
#else
#define snd_ali_printk(format, args...)
#endif
@@ -105,10 +105,10 @@ module_param(enable, bool, 0444);
* Direct Registers
*/
-#define ALI_LEGACY_DMAR0 0x00 // ADR0
-#define ALI_LEGACY_DMAR4 0x04 // CNT0
-#define ALI_LEGACY_DMAR11 0x0b // MOD
-#define ALI_LEGACY_DMAR15 0x0f // MMR
+#define ALI_LEGACY_DMAR0 0x00 /* ADR0 */
+#define ALI_LEGACY_DMAR4 0x04 /* CNT0 */
+#define ALI_LEGACY_DMAR11 0x0b /* MOD */
+#define ALI_LEGACY_DMAR15 0x0f /* MMR */
#define ALI_MPUR0 0x20
#define ALI_MPUR1 0x21
#define ALI_MPUR2 0x22
@@ -175,7 +175,7 @@ struct snd_ali;
struct snd_ali_voice;
struct snd_ali_channel_control {
- // register data
+ /* register data */
struct REGDATA {
unsigned int start;
unsigned int stop;
@@ -183,7 +183,7 @@ struct snd_ali_channel_control {
unsigned int ainten;
} data;
- // register addresses
+ /* register addresses */
struct REGS {
unsigned int start;
unsigned int stop;
@@ -197,19 +197,18 @@ struct snd_ali_channel_control {
struct snd_ali_voice {
unsigned int number;
- unsigned int use: 1,
- pcm: 1,
- midi: 1,
- mode: 1,
- synth: 1;
+ unsigned int use :1,
+ pcm :1,
+ midi :1,
+ mode :1,
+ synth :1,
+ running :1;
/* PCM data */
struct snd_ali *codec;
struct snd_pcm_substream *substream;
struct snd_ali_voice *extra;
- unsigned int running: 1;
-
int eso; /* final ESO value for channel */
int count; /* runtime->period_size */
@@ -231,14 +230,12 @@ struct snd_alidev {
};
-#ifdef CONFIG_PM
#define ALI_GLOBAL_REGS 56
#define ALI_CHANNEL_REGS 8
struct snd_ali_image {
- unsigned long regs[ALI_GLOBAL_REGS];
- unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
+ u32 regs[ALI_GLOBAL_REGS];
+ u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
};
-#endif
struct snd_ali {
@@ -246,8 +243,8 @@ struct snd_ali {
unsigned long port;
unsigned char revision;
- unsigned int hw_initialized: 1;
- unsigned int spdif_support: 1;
+ unsigned int hw_initialized :1;
+ unsigned int spdif_support :1;
struct pci_dev *pci;
struct pci_dev *pci_m1533;
@@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids);
static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int);
static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short);
-static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short);
-
-/*
- * Debug Part
- */
-
-#ifdef ALI_DEBUG
-
-static void ali_read_regs(struct snd_ali *codec, int channel)
-{
- int i,j;
- unsigned int dwVal;
-
- printk("channel %d registers map:\n", channel);
- outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR));
-
- printk(" ");
- for(j=0;j<8;j++)
- printk("%2.2x ", j*4);
- printk("\n");
-
- for (i=0; i<=0xf8/4;i++) {
- if(i%8 == 0)
- printk("%2.2x ", (i*4/0x10)*0x10);
- dwVal = inl(ALI_REG(codec,i*4));
- printk("%8.8x ", dwVal);
- if ((i+1)%8 == 0)
- printk("\n");
- }
- printk("\n");
-}
-static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
-{
- unsigned int dwVal;
- struct pci_dev *pci_dev;
- int i,j;
-
- pci_dev = pci_get_device(vendor, deviceid, NULL);
- if (pci_dev == NULL)
- return ;
-
- printk("\nM%x PCI CFG\n", deviceid);
- printk(" ");
- for(j=0;j<8;j++)
- printk("%d ",j);
- printk("\n");
-
- for(i=0;i<8;i++) {
- printk("%d ",i);
- for(j=0;j<8;j++)
- {
- pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal);
- printk("%8.8x ", dwVal);
- }
- printk("\n");
- }
- pci_dev_put(pci_dev);
- }
-static void ali_read_ac97regs(struct snd_ali *codec, int secondary)
-{
- unsigned short i,j;
- unsigned short wVal;
-
- printk("\ncodec %d registers map:\n", secondary);
-
- printk(" ");
- for(j=0;j<8;j++)
- printk("%2.2x ",j*2);
- printk("\n");
-
- for (i=0; i<64;i++) {
- if(i%8 == 0)
- printk("%2.2x ", (i/8)*0x10);
- wVal = snd_ali_codec_peek(codec, secondary, i*2);
- printk("%4.4x ", wVal);
- if ((i+1)%8 == 0)
- printk("\n");
- }
- printk("\n");
-}
-
-#endif
+static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short,
+ unsigned short);
/*
* AC97 ACCESS
*/
static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec,
- unsigned int port )
+ unsigned int port)
{
return (unsigned int)inl(ALI_REG(codec, port));
}
-static inline void snd_ali_5451_poke( struct snd_ali *codec,
- unsigned int port,
- unsigned int val )
+static inline void snd_ali_5451_poke(struct snd_ali *codec,
+ unsigned int port,
+ unsigned int val)
{
outl((unsigned int)val, ALI_REG(codec, port));
}
-static int snd_ali_codec_ready( struct snd_ali *codec,
- unsigned int port )
+static int snd_ali_codec_ready(struct snd_ali *codec,
+ unsigned int port)
{
unsigned long end_time;
unsigned int res;
@@ -396,7 +313,7 @@ static int snd_ali_codec_ready( struct snd_ali *codec,
end_time = jiffies + msecs_to_jiffies(250);
do {
res = snd_ali_5451_peek(codec,port);
- if (! (res & 0x8000))
+ if (!(res & 0x8000))
return 0;
schedule_timeout_uninterruptible(1);
} while (time_after_eq(end_time, jiffies));
@@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec)
}
static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
- unsigned short reg,
- unsigned short val)
+ unsigned short reg,
+ unsigned short val)
{
- unsigned int dwVal = 0;
- unsigned int port = 0;
+ unsigned int dwVal;
+ unsigned int port;
if (reg >= 0x80) {
snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
@@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
dwVal = (unsigned int) (reg & 0xff);
dwVal |= 0x8000 | (val << 16);
- if (secondary) dwVal |= 0x0080;
- if (codec->revision == ALI_5451_V02) dwVal |= 0x0100;
+ if (secondary)
+ dwVal |= 0x0080;
+ if (codec->revision == ALI_5451_V02)
+ dwVal |= 0x0100;
- snd_ali_5451_poke(codec,port,dwVal);
+ snd_ali_5451_poke(codec, port, dwVal);
return ;
}
-static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
- int secondary,
- unsigned short reg)
+static unsigned short snd_ali_codec_peek(struct snd_ali *codec,
+ int secondary,
+ unsigned short reg)
{
- unsigned int dwVal = 0;
- unsigned int port = 0;
+ unsigned int dwVal;
+ unsigned int port;
if (reg >= 0x80) {
snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
@@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
dwVal = (unsigned int) (reg & 0xff);
dwVal |= 0x8000; /* bit 15*/
- if (secondary) dwVal |= 0x0080;
+ if (secondary)
+ dwVal |= 0x0080;
snd_ali_5451_poke(codec, port, dwVal);
@@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
if (snd_ali_codec_ready(codec, port) < 0)
return ~0;
- return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16;
+ return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16;
}
static void snd_ali_codec_write(struct snd_ac97 *ac97,
@@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97,
struct snd_ali *codec = ac97->private_data;
snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
- if(reg == AC97_GPIO_STATUS) {
- outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE,
- ALI_REG(codec, ALI_AC97_GPIO));
+ if (reg == AC97_GPIO_STATUS) {
+ outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE,
+ ALI_REG(codec, ALI_AC97_GPIO));
return;
}
snd_ali_codec_poke(codec, ac97->num, reg, val);
@@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97,
}
-static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg)
+static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97,
+ unsigned short reg)
{
struct snd_ali *codec = ac97->private_data;
snd_ali_printk("codec_read reg=%xh.\n", reg);
- return (snd_ali_codec_peek(codec, ac97->num, reg));
+ return snd_ali_codec_peek(codec, ac97->num, reg);
}
/*
@@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r
static int snd_ali_reset_5451(struct snd_ali *codec)
{
- struct pci_dev *pci_dev = NULL;
+ struct pci_dev *pci_dev;
unsigned short wCount, wReg;
unsigned int dwVal;
- if ((pci_dev = codec->pci_m1533) != NULL) {
+ pci_dev = codec->pci_m1533;
+ if (pci_dev) {
pci_read_config_dword(pci_dev, 0x7c, &dwVal);
pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
udelay(5000);
@@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
wCount = 200;
while(wCount--) {
wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN);
- if((wReg & 0x000f) == 0x000f)
+ if ((wReg & 0x000f) == 0x000f)
return 0;
udelay(5000);
}
@@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
static int snd_ali_reset_codec(struct snd_ali *codec)
{
- struct pci_dev *pci_dev = NULL;
- unsigned char bVal = 0;
+ struct pci_dev *pci_dev;
+ unsigned char bVal;
unsigned int dwVal;
unsigned short wCount, wReg;
@@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec)
udelay(15000);
wCount = 200;
- while(wCount--) {
+ while (wCount--) {
wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN);
- if((wReg & 0x000f) == 0x000f)
+ if ((wReg & 0x000f) == 0x000f)
return 0;
udelay(5000);
}
@@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec)
* ALI 5451 Controller
*/
-static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_enable_special_channel(struct snd_ali *codec,
+ unsigned int channel)
{
- unsigned long dwVal = 0;
+ unsigned long dwVal;
- dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
+ dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
dwVal |= 1 << (channel & 0x0000001f);
- outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
+ outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
}
-static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_disable_special_channel(struct snd_ali *codec,
+ unsigned int channel)
{
- unsigned long dwVal = 0;
+ unsigned long dwVal;
- dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
+ dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
dwVal &= ~(1 << (channel & 0x0000001f));
- outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
+ outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
}
-static void snd_ali_enable_address_interrupt(struct snd_ali * codec)
+static void snd_ali_enable_address_interrupt(struct snd_ali *codec)
{
unsigned int gc;
@@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec)
outl( gc, ALI_REG(codec, ALI_GC_CIR));
}
-static void snd_ali_disable_address_interrupt(struct snd_ali * codec)
+static void snd_ali_disable_address_interrupt(struct snd_ali *codec)
{
unsigned int gc;
@@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec)
outl(gc, ALI_REG(codec, ALI_GC_CIR));
}
-#if 0 // not used
-static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel)
+#if 0 /* not used */
+static void snd_ali_enable_voice_irq(struct snd_ali *codec,
+ unsigned int channel)
{
unsigned int mask;
struct snd_ali_channel_control *pchregs = &(codec->chregs);
@@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel
snd_ali_printk("enable_voice_irq channel=%d\n",channel);
mask = 1 << (channel & 0x1f);
- pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten));
+ pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten));
pchregs->data.ainten |= mask;
- outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
+ outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
}
#endif
-static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_disable_voice_irq(struct snd_ali *codec,
+ unsigned int channel)
{
unsigned int mask;
struct snd_ali_channel_control *pchregs = &(codec->chregs);
@@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe
snd_ali_printk("disable_voice_irq channel=%d\n",channel);
mask = 1 << (channel & 0x1f);
- pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten));
+ pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten));
pchregs->data.ainten &= ~mask;
- outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
+ outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
}
static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
@@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
unsigned int idx = channel & 0x1f;
if (codec->synth.chcnt >= ALI_CHANNELS){
- snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
+ snd_printk(KERN_ERR
+ "ali_alloc_pcm_channel: no free channels.\n");
return -1;
}
@@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec)
snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm");
- // recording
+ /* recording */
if (rec) {
if (codec->spdif_support &&
- (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT))
+ (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+ ALI_SPDIF_IN_SUPPORT))
idx = ALI_SPDIF_IN_CHANNEL;
else
idx = ALI_PCM_IN_CHANNEL;
- if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
+ result = snd_ali_alloc_pcm_channel(codec, idx);
+ if (result >= 0)
return result;
- } else {
- snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
+ else {
+ snd_printk(KERN_ERR "ali_find_free_channel: "
+ "record channel is busy now.\n");
return -1;
}
}
- //playback...
+ /* playback... */
if (codec->spdif_support &&
- (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) {
+ (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+ ALI_SPDIF_OUT_CH_ENABLE)) {
idx = ALI_SPDIF_OUT_CHANNEL;
- if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
+ result = snd_ali_alloc_pcm_channel(codec, idx);
+ if (result >= 0)
return result;
- } else {
- snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
- }
+ else
+ snd_printk(KERN_ERR "ali_find_free_channel: "
+ "S/PDIF out channel is in busy now.\n");
}
for (idx = 0; idx < ALI_CHANNELS; idx++) {
- if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
+ result = snd_ali_alloc_pcm_channel(codec, idx);
+ if (result >= 0)
return result;
}
snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
@@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
return;
if (!(codec->synth.chmap & (1 << idx))) {
- snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel);
+ snd_printk(KERN_ERR "ali_free_channel_pcm: "
+ "channel %d is not in use.\n", channel);
return;
} else {
codec->synth.chmap &= ~(1 << idx);
@@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
}
}
-#if 0 // not used
-static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel)
+#if 0 /* not used */
+static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel)
{
unsigned int mask = 1 << (channel & 0x1f);
@@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel)
}
#endif
-static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel)
+static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel)
{
unsigned int mask = 1 << (channel & 0x1f);
@@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval)
currenttimer = inl(ALI_REG(codec, ALI_STIMER));
while (currenttimer < begintimer + interval) {
- if(snd_ali_stimer_ready(codec) < 0)
+ if (snd_ali_stimer_ready(codec) < 0)
break;
currenttimer = inl(ALI_REG(codec, ALI_STIMER));
+ cpu_relax();
}
}
static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
{
- u16 wval = 0;
+ u16 wval;
u16 count = 0;
- u8 bval = 0, R1 = 0, R2 = 0;
+ u8 bval, R1 = 0, R2;
- bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+ bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
bval |= 0x1F;
- outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+ outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1));
- while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) {
+ while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) {
count ++;
snd_ali_delay(codec, 6);
- bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+ bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
R1 = bval & 0x1F;
}
@@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
snd_ali_delay(codec, 6);
bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
R2 = bval & 0x1F;
- if (R2 != R1) R1 = R2; else break;
+ if (R2 != R1)
+ R1 = R2;
+ else
+ break;
}
if (count > 50000) {
@@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
}
if (R2 >= 0x0b && R2 <= 0x0e) {
- wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
- wval &= 0xE0F0;
- wval |= (u16)0x09 << 8 | (u16)0x05;
- outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
+ wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
+ wval &= 0xe0f0;
+ wval |= (0x09 << 8) | 0x05;
+ outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
- bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
- outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3));
+ bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0;
+ outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3));
} else if (R2 == 0x12) {
- wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
- wval &= 0xE0F0;
- wval |= (u16)0x0E << 8 | (u16)0x08;
- outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
+ wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
+ wval &= 0xe0f0;
+ wval |= (0x0e << 8) | 0x08;
+ outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
- bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
- outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3));
+ bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0;
+ outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3));
}
}
static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec)
{
- u32 dwRate = 0;
- u8 bval = 0;
+ u32 dwRate;
+ u8 bval;
- bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
- bval &= 0x7F;
+ bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
+ bval &= 0x7f;
bval |= 0x40;
- outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL));
+ outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL));
snd_ali_detect_spdif_rate(codec);
- bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3));
- bval &= 0x0F;
+ bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3));
+ bval &= 0x0f;
- if (bval == 0) dwRate = 44100;
- if (bval == 1) dwRate = 48000;
- if (bval == 2) dwRate = 32000;
+ switch (bval) {
+ case 0: dwRate = 44100; break;
+ case 1: dwRate = 48000; break;
+ case 2: dwRate = 32000; break;
+ default: dwRate = 0; break;
+ }
return dwRate;
}
@@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec)
static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate)
{
unsigned char bVal;
- unsigned int dwRate = 0;
+ unsigned int dwRate;
- if (rate == 32000) dwRate = 0x300;
- if (rate == 44100) dwRate = 0;
- if (rate == 48000) dwRate = 0x200;
+ switch (rate) {
+ case 32000: dwRate = 0x300; break;
+ case 48000: dwRate = 0x200; break;
+ default: dwRate = 0; break;
+ }
bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
bVal &= (unsigned char)(~(1<<6));
- bVal |= 0x80; //select right
+ bVal |= 0x80; /* select right */
outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2));
- bVal &= (~0x80); //select left
+ bVal &= ~0x80; /* select left */
outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2));
}
@@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec)
{
unsigned short wVal;
unsigned char bVal;
-
- struct pci_dev *pci_dev = NULL;
+ struct pci_dev *pci_dev;
pci_dev = codec->pci_m1533;
if (pci_dev == NULL)
@@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec)
bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL));
- {
- wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
- wVal |= ALI_SPDIF_OUT_SEL_PCM;
- outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
- snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
- }
+ wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
+ wVal |= ALI_SPDIF_OUT_SEL_PCM;
+ outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
+ snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
}
static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
{
- unsigned short wVal = 0;
+ unsigned short wVal;
wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
wVal &= ~ALI_SPDIF_OUT_SEL_PCM;
@@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
wVal &= (~0x0002);
outw(wVal, ALI_REG(codec, ALI_SPDIF_CS));
*/
- snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
+ snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
}
static void snd_ali_disable_spdif_chnout(struct snd_ali *codec)
{
- unsigned short wVal = 0;
+ unsigned short wVal;
+
wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
wVal |= ALI_SPDIF_OUT_SEL_PCM;
outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
@@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec)
snd_ali_disable_spdif_chnout(codec);
}
-static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
+static void snd_ali_update_ptr(struct snd_ali *codec, int channel)
{
- struct snd_ali_voice *pvoice = NULL;
+ struct snd_ali_voice *pvoice;
struct snd_pcm_runtime *runtime;
- struct snd_ali_channel_control *pchregs = NULL;
+ struct snd_ali_channel_control *pchregs;
unsigned int old, mask;
#ifdef ALI_DEBUG
unsigned int temp, cspf;
@@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
pchregs = &(codec->chregs);
- // check if interrupt occurred for channel
+ /* check if interrupt occurred for channel */
old = pchregs->data.aint;
- mask = ((unsigned int) 1L) << (channel & 0x1f);
+ mask = 1U << (channel & 0x1f);
if (!(old & mask))
return;
@@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask;
#endif
if (pvoice->running) {
- snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf);
+ snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",
+ (u16)temp, cspf);
spin_unlock(&codec->reg_lock);
snd_pcm_period_elapsed(pvoice->substream);
spin_lock(&codec->reg_lock);
@@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
pchregs->data.aint = old & (~mask);
}
-static void snd_ali_interrupt(struct snd_ali * codec)
+static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
{
+ struct snd_ali *codec = dev_id;
int channel;
unsigned int audio_int;
- struct snd_ali_channel_control *pchregs = NULL;
- pchregs = &(codec->chregs);
+ struct snd_ali_channel_control *pchregs;
+
+ if (codec == NULL || !codec->hw_initialized)
+ return IRQ_NONE;
audio_int = inl(ALI_REG(codec, ALI_MISCINT));
+ if (!audio_int)
+ return IRQ_NONE;
+
+ pchregs = &(codec->chregs);
if (audio_int & ADDRESS_IRQ) {
- // get interrupt status for all channels
- pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint));
- for (channel = 0; channel < ALI_CHANNELS; channel++) {
+ /* get interrupt status for all channels */
+ pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint));
+ for (channel = 0; channel < ALI_CHANNELS; channel++)
snd_ali_update_ptr(codec, channel);
- }
}
outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
- ALI_REG(codec,ALI_MISCINT));
-}
-
-
-static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
-{
- struct snd_ali *codec = dev_id;
+ ALI_REG(codec, ALI_MISCINT));
- if (codec == NULL)
- return IRQ_NONE;
- snd_ali_interrupt(codec);
return IRQ_HANDLED;
}
-static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel)
+static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec,
+ int type, int rec, int channel)
{
- struct snd_ali_voice *pvoice = NULL;
+ struct snd_ali_voice *pvoice;
int idx;
- snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec);
+ snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec);
spin_lock_irq(&codec->voice_alloc);
if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
snd_ali_find_free_channel(codec,rec);
- if(idx < 0) {
+ if (idx < 0) {
snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
spin_unlock_irq(&codec->voice_alloc);
return NULL;
@@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ
}
-static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice)
+static void snd_ali_free_voice(struct snd_ali * codec,
+ struct snd_ali_voice *pvoice)
{
void (*private_free)(void *);
void *private_data;
@@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo
private_data = pvoice->private_data;
pvoice->private_free = NULL;
pvoice->private_data = NULL;
- if (pvoice->pcm) {
+ if (pvoice->pcm)
snd_ali_free_channel_pcm(codec, pvoice->number);
- }
pvoice->use = pvoice->pcm = pvoice->synth = 0;
pvoice->substream = NULL;
spin_unlock_irq(&codec->voice_alloc);
@@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo
}
-static void snd_ali_clear_voices(struct snd_ali * codec,
- unsigned int v_min,
- unsigned int v_max)
+static void snd_ali_clear_voices(struct snd_ali *codec,
+ unsigned int v_min,
+ unsigned int v_max)
{
unsigned int i;
@@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec,
}
}
-static void snd_ali_write_voice_regs(struct snd_ali * codec,
+static void snd_ali_write_voice_regs(struct snd_ali *codec,
unsigned int Channel,
unsigned int LBA,
unsigned int CSO,
@@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec,
{
unsigned int ctlcmds[4];
- outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR));
+ outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR));
ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff);
ctlcmds[1] = LBA;
@@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec,
outb(Channel, ALI_REG(codec, ALI_GC_CIR));
- outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS));
- outl(ctlcmds[1], ALI_REG(codec,ALI_LBA));
- outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA));
- outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC));
+ outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS));
+ outl(ctlcmds[1], ALI_REG(codec, ALI_LBA));
+ outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA));
+ outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC));
outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */
outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */
@@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec)
{
unsigned int delta;
- if (rate < 4000) rate = 4000;
- if (rate > 48000) rate = 48000;
+ if (rate < 4000)
+ rate = 4000;
+ if (rate > 48000)
+ rate = 48000;
if (rec) {
if (rate == 44100)
@@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
*/
CTRL = 0x00000001;
if (snd_pcm_format_width(runtime->format) == 16)
- CTRL |= 0x00000008; // 16-bit data
+ CTRL |= 0x00000008; /* 16-bit data */
if (!snd_pcm_format_unsigned(runtime->format))
- CTRL |= 0x00000002; // signed data
+ CTRL |= 0x00000002; /* signed data */
if (runtime->channels > 1)
- CTRL |= 0x00000004; // stereo data
+ CTRL |= 0x00000004; /* stereo data */
return CTRL;
}
@@ -1213,45 +1155,39 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
* PCM part
*/
-static int snd_ali_ioctl(struct snd_pcm_substream *substream,
- unsigned int cmd, void *arg)
-{
- return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
static int snd_ali_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct snd_ali *codec = snd_pcm_substream_chip(substream);
- struct list_head *pos;
struct snd_pcm_substream *s;
unsigned int what, whati, capture_flag;
- struct snd_ali_voice *pvoice = NULL, *evoice = NULL;
+ struct snd_ali_voice *pvoice, *evoice;
unsigned int val;
int do_start;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
- do_start = 1; break;
+ do_start = 1;
+ break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
- do_start = 0; break;
+ do_start = 0;
+ break;
default:
return -EINVAL;
}
what = whati = capture_flag = 0;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) {
pvoice = s->runtime->private_data;
evoice = pvoice->extra;
what |= 1 << (pvoice->number & 0x1f);
- if (evoice == NULL) {
+ if (evoice == NULL)
whati |= 1 << (pvoice->number & 0x1f);
- } else {
+ else {
whati |= 1 << (evoice->number & 0x1f);
what |= 1 << (evoice->number & 0x1f);
}
@@ -1270,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream,
}
}
spin_lock(&codec->reg_lock);
- if (! do_start) {
+ if (!do_start)
outl(what, ALI_REG(codec, ALI_STOP));
- }
val = inl(ALI_REG(codec, ALI_AINTEN));
- if (do_start) {
+ if (do_start)
val |= whati;
- } else {
+ else
val &= ~whati;
- }
outl(val, ALI_REG(codec, ALI_AINTEN));
- if (do_start) {
+ if (do_start)
outl(what, ALI_REG(codec, ALI_START));
- }
- snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati);
+ snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati);
spin_unlock(&codec->reg_lock);
return 0;
}
static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
+ struct snd_pcm_hw_params *hw_params)
{
struct snd_ali *codec = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ali_voice *pvoice = runtime->private_data;
struct snd_ali_voice *evoice = pvoice->extra;
int err;
- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
- if (err < 0) return err;
+
+ err = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (err < 0)
+ return err;
/* voice management */
- if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) {
- if (evoice == NULL) {
- evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1);
- if (evoice == NULL)
+ if (params_buffer_size(hw_params) / 2 !=
+ params_period_size(hw_params)) {
+ if (!evoice) {
+ evoice = snd_ali_alloc_voice(codec,
+ SNDRV_ALI_VOICE_TYPE_PCM,
+ 0, -1);
+ if (!evoice)
return -ENOMEM;
pvoice->extra = evoice;
evoice->substream = substream;
}
} else {
- if (evoice != NULL) {
+ if (!evoice) {
snd_ali_free_voice(codec, evoice);
pvoice->extra = evoice = NULL;
}
@@ -1328,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL;
snd_pcm_lib_free_pages(substream);
- if (evoice != NULL) {
+ if (!evoice) {
snd_ali_free_voice(codec, evoice);
pvoice->extra = NULL;
}
@@ -1336,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
}
static int snd_ali_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
+ struct snd_pcm_hw_params *hw_params)
{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+ return snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
}
static int snd_ali_hw_free(struct snd_pcm_substream *substream)
@@ -1369,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
/* set Delta (rate) value */
Delta = snd_ali_convert_rate(runtime->rate, 0);
- if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) ||
- (pvoice->number == ALI_PCM_IN_CHANNEL))
+ if (pvoice->number == ALI_SPDIF_IN_CHANNEL ||
+ pvoice->number == ALI_PCM_IN_CHANNEL)
snd_ali_disable_special_channel(codec, pvoice->number);
else if (codec->spdif_support &&
- (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)
- && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) {
+ (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+ ALI_SPDIF_OUT_CH_ENABLE)
+ && pvoice->number == ALI_SPDIF_OUT_CHANNEL) {
snd_ali_set_spdif_out_rate(codec, runtime->rate);
Delta = 0x1000;
}
@@ -1388,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
/* set target ESO for channel */
pvoice->eso = runtime->buffer_size;
- snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count);
+ snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",
+ pvoice->eso, pvoice->count);
/* set ESO to capture first MIDLP interrupt */
ESO = pvoice->eso -1;
@@ -1399,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
PAN = 0;
VOL = 0;
EC = 0;
- snd_ali_printk("playback_prepare:\n ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
- snd_ali_write_voice_regs( codec,
- pvoice->number,
- LBA,
- 0, /* cso */
- ESO,
- Delta,
- 0, /* alpha */
- GVSEL,
- PAN,
- VOL,
- CTRL,
- EC);
- if (evoice != NULL) {
+ snd_ali_printk("playback_prepare:\n");
+ snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",
+ pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
+ snd_ali_write_voice_regs(codec,
+ pvoice->number,
+ LBA,
+ 0, /* cso */
+ ESO,
+ Delta,
+ 0, /* alpha */
+ GVSEL,
+ PAN,
+ VOL,
+ CTRL,
+ EC);
+ if (!evoice) {
evoice->count = pvoice->count;
evoice->eso = pvoice->count << 1;
ESO = evoice->eso - 1;
snd_ali_write_voice_regs(codec,
- evoice->number,
- LBA,
- 0, /* cso */
- ESO,
- Delta,
- 0, /* alpha */
- GVSEL,
- (unsigned int)0x7f,
- (unsigned int)0x3ff,
- CTRL,
- EC);
+ evoice->number,
+ LBA,
+ 0, /* cso */
+ ESO,
+ Delta,
+ 0, /* alpha */
+ GVSEL,
+ 0x7f,
+ 0x3ff,
+ CTRL,
+ EC);
}
spin_unlock_irq(&codec->reg_lock);
return 0;
@@ -1459,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
pvoice->number == ALI_MODEM_OUT_CHANNEL) ?
0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode);
- // Prepare capture intr channel
+ /* Prepare capture intr channel */
if (pvoice->number == ALI_SPDIF_IN_CHANNEL) {
unsigned int rate;
@@ -1470,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
rate = snd_ali_get_spdif_in_rate(codec);
if (rate == 0) {
- snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
+ snd_printk(KERN_WARNING "ali_capture_preapre: "
+ "spdif rate detect err!\n");
rate = 48000;
}
spin_lock_irq(&codec->reg_lock);
@@ -1481,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
}
if (rate != 48000)
- Delta = ((rate << 12)/runtime->rate)&0x00ffff;
+ Delta = ((rate << 12) / runtime->rate) & 0x00ffff;
}
- // set target ESO for channel
+ /* set target ESO for channel */
pvoice->eso = runtime->buffer_size;
- // set interrupt count size
+ /* set interrupt count size */
pvoice->count = runtime->period_size;
- // set Loop Back Address
+ /* set Loop Back Address */
LBA = runtime->dma_addr;
- // set ESO to capture first MIDLP interrupt
+ /* set ESO to capture first MIDLP interrupt */
ESO = pvoice->eso - 1;
CTRL = snd_ali_control_mode(substream);
GVSEL = 0;
@@ -1514,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
CTRL,
EC);
-
spin_unlock_irq(&codec->reg_lock);
return 0;
}
-static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t
+snd_ali_playback_pointer(struct snd_pcm_substream *substream)
{
struct snd_ali *codec = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1563,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
static struct snd_pcm_hardware snd_ali_playback =
{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
.rate_min = 4000,
.rate_max = 48000,
.channels_min = 1,
@@ -1589,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback =
static struct snd_pcm_hardware snd_ali_capture =
{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
.rate_min = 4000,
.rate_max = 48000,
.channels_min = 1,
@@ -1620,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime)
}
}
-static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel,
- struct snd_pcm_hardware *phw)
+static int snd_ali_open(struct snd_pcm_substream *substream, int rec,
+ int channel, struct snd_pcm_hardware *phw)
{
struct snd_ali *codec = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ali_voice *pvoice;
- pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel);
- if (pvoice == NULL)
+ pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec,
+ channel);
+ if (!pvoice)
return -EAGAIN;
pvoice->substream = substream;
@@ -1637,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe
runtime->hw = *phw;
snd_pcm_set_sync(substream);
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ 0, 64*1024);
return 0;
}
@@ -1669,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream)
static struct snd_pcm_ops snd_ali_playback_ops = {
.open = snd_ali_playback_open,
.close = snd_ali_playback_close,
- .ioctl = snd_ali_ioctl,
+ .ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_ali_playback_hw_params,
.hw_free = snd_ali_playback_hw_free,
.prepare = snd_ali_playback_prepare,
@@ -1680,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = {
static struct snd_pcm_ops snd_ali_capture_ops = {
.open = snd_ali_capture_open,
.close = snd_ali_close,
- .ioctl = snd_ali_ioctl,
+ .ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_ali_hw_params,
.hw_free = snd_ali_hw_free,
.prepare = snd_ali_prepare,
@@ -1697,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream,
{
struct snd_ali *chip = snd_pcm_substream_chip(substream);
unsigned int modem_num = chip->num_of_codecs - 1;
- snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params));
+ snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE,
+ params_rate(hw_params));
snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0);
return snd_ali_hw_params(substream, hw_params);
}
static struct snd_pcm_hardware snd_ali_modem =
{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000,
+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000),
.rate_min = 8000,
.rate_max = 16000,
.channels_min = 1,
@@ -1723,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem =
.fifo_size = 0,
};
-static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel)
+static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec,
+ int channel)
{
- static unsigned int rates [] = {8000,9600,12000,16000};
+ static unsigned int rates[] = {8000, 9600, 12000, 16000};
static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
.count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,
};
int err = snd_ali_open(substream, rec, channel, &snd_ali_modem);
+
if (err)
return err;
return snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -1788,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm)
}
-static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc)
+static int __devinit snd_ali_pcm(struct snd_ali * codec, int device,
+ struct ali_pcm_description *desc)
{
struct snd_pcm *pcm;
int err;
@@ -1802,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_
pcm->private_data = codec;
pcm->private_free = snd_ali_pcm_free;
if (desc->playback_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ desc->playback_ops);
if (desc->capture_ops)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ desc->capture_ops);
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
+ snd_dma_pci_data(codec->pci),
+ 64*1024, 128*1024);
pcm->info_flags = 0;
pcm->dev_class = desc->class;
@@ -1818,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_
}
static struct ali_pcm_description ali_pcms[] = {
- { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
- { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
+ { .name = "ALI 5451",
+ .playback_num = ALI_CHANNELS,
+ .capture_num = 1,
+ .playback_ops = &snd_ali_playback_ops,
+ .capture_ops = &snd_ali_capture_ops
+ },
+ { .name = "ALI 5451 modem",
+ .playback_num = 1,
+ .capture_num = 1,
+ .playback_ops = &snd_ali_modem_playback_ops,
+ .capture_ops = &snd_ali_modem_capture_ops,
+ .class = SNDRV_PCM_CLASS_MODEM
+ }
};
static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
{
int i, err;
- for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++)
- if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0)
+ for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) {
+ err = snd_ali_pcm(codec, i, &ali_pcms[i]);
+ if (err < 0)
return err;
+ }
return 0;
}
@@ -1837,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
.info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
.put = snd_ali5451_spdif_put, .private_value = value}
-static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
@@ -1846,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
return 0;
}
-static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ali *codec = kcontrol->private_data;
unsigned int enable;
@@ -1854,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
enable = ucontrol->value.integer.value[0] ? 1 : 0;
spin_lock_irq(&codec->reg_lock);
- switch(kcontrol->private_value) {
+ switch (kcontrol->private_value) {
case 0:
enable = (codec->spdif_mask & 0x02) ? 1 : 0;
break;
case 1:
- enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0;
+ enable = ((codec->spdif_mask & 0x02) &&
+ (codec->spdif_mask & 0x04)) ? 1 : 0;
break;
case 2:
enable = (codec->spdif_mask & 0x01) ? 1 : 0;
@@ -1872,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
return 0;
}
-static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ali *codec = kcontrol->private_data;
unsigned int change = 0, enable = 0;
@@ -1939,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = {
ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
};
-static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
- struct snd_ali *codec = bus->private_data;
- codec->ac97_bus = NULL;
-}
-
-static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97)
-{
- struct snd_ali *codec = ac97->private_data;
- codec->ac97[ac97->num] = NULL;
-}
-
static int __devinit snd_ali_mixer(struct snd_ali * codec)
{
struct snd_ac97_template ac97;
@@ -1961,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
.read = snd_ali_codec_read,
};
- if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0)
+ err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus);
+ if (err < 0)
return err;
- codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = codec;
- ac97.private_free = snd_ali_mixer_free_ac97;
- for ( i = 0 ; i < codec->num_of_codecs ; i++) {
+ for (i = 0; i < codec->num_of_codecs; i++) {
ac97.num = i;
- if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
- snd_printk(KERN_ERR "ali mixer %d creating error.\n", i);
- if(i == 0)
+ err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]);
+ if (err < 0) {
+ snd_printk(KERN_ERR
+ "ali mixer %d creating error.\n", i);
+ if (i == 0)
return err;
codec->num_of_codecs = 1;
break;
@@ -1981,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
}
if (codec->spdif_support) {
- for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
- err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
- if (err < 0) return err;
+ for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
+ err = snd_ctl_add(codec->card,
+ snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
+ if (err < 0)
+ return err;
}
}
return 0;
@@ -1998,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
int i, j;
im = chip->image;
- if (! im)
+ if (!im)
return 0;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- for(i = 0 ; i < chip->num_of_codecs ; i++) {
+ for (i = 0; i < chip->num_of_codecs; i++) {
snd_pcm_suspend_all(chip->pcm[i]);
snd_ac97_suspend(chip->ac97[i]);
}
@@ -2010,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
spin_lock_irq(&chip->reg_lock);
im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));
- // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START));
+ /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */
im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP));
- // disable all IRQ bits
+ /* disable all IRQ bits */
outl(0, ALI_REG(chip, ALI_MISCINT));
for (i = 0; i < ALI_GLOBAL_REGS; i++) {
@@ -2028,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0));
}
- // stop all HW channel
+ /* stop all HW channel */
outl(0xffffffff, ALI_REG(chip, ALI_STOP));
spin_unlock_irq(&chip->reg_lock);
@@ -2047,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci)
int i, j;
im = chip->image;
- if (! im)
+ if (!im)
return 0;
pci_set_power_state(pci, PCI_D0);
@@ -2069,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci)
}
for (i = 0; i < ALI_GLOBAL_REGS; i++) {
- if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START))
+ if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) ||
+ (i*4 == ALI_START))
continue;
outl(im->regs[i], ALI_REG(chip, i*4));
}
- // start HW channel
+ /* start HW channel */
outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
- // restore IRQ enable bits
+ /* restore IRQ enable bits */
outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
spin_unlock_irq(&chip->reg_lock);
- for(i = 0 ; i < chip->num_of_codecs ; i++)
+ for (i = 0 ; i < chip->num_of_codecs; i++)
snd_ac97_resume(chip->ac97[i]);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2113,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec)
{
unsigned int legacy;
unsigned char temp;
- struct pci_dev *pci_dev = NULL;
+ struct pci_dev *pci_dev;
snd_ali_printk("chip initializing ... \n");
@@ -2146,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec)
outb(0x10, ALI_REG(codec, ALI_MPUR2));
codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID);
- codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS);
+ codec->ac97_ext_status = snd_ali_codec_peek(codec, 0,
+ AC97_EXTENDED_STATUS);
if (codec->spdif_support) {
snd_ali_enable_spdif_out(codec);
codec->spdif_mask = 0x00000002;
@@ -2158,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec)
if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) {
codec->num_of_codecs++;
outl(inl(ALI_REG(codec, ALI_SCTRL)) |
- (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN),
- ALI_REG(codec, ALI_SCTRL));
+ (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 |
+ ALI_SCTRL_LINE_OUT_EN),
+ ALI_REG(codec, ALI_SCTRL));
}
snd_ali_printk("chip initialize succeed.\n");
@@ -2168,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec)
}
/* proc for register dump */
-static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
+static void snd_ali_proc_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buf)
{
struct snd_ali *codec = entry->private_data;
int i;
- for(i = 0 ; i < 256 ; i+= 4)
+ for (i = 0; i < 256 ; i+= 4)
snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
}
static void __devinit snd_ali_proc_init(struct snd_ali *codec)
{
struct snd_info_entry *entry;
- if(!snd_card_proc_new(codec->card, "ali5451", &entry))
+ if (!snd_card_proc_new(codec->card, "ali5451", &entry))
snd_info_set_text_ops(entry, codec, snd_ali_proc_read);
}
@@ -2188,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
int err;
snd_ali_printk("resouces allocation ...\n");
- if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0)
+ err = pci_request_regions(codec->pci, "ALI 5451");
+ if (err < 0)
return err;
codec->port = pci_resource_start(codec->pci, 0);
@@ -2201,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
snd_ali_printk("resouces allocated.\n");
return 0;
}
-static int snd_ali_dev_free(struct snd_device *device)
+static int snd_ali_dev_free(struct snd_device *device)
{
- struct snd_ali *codec=device->device_data;
+ struct snd_ali *codec = device->device_data;
snd_ali_free(codec);
return 0;
}
@@ -2226,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card,
snd_ali_printk("creating ...\n");
/* enable PCI device */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 31 bits */
if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 ||
pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) {
- snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n");
+ snd_printk(KERN_ERR "architecture does not support "
+ "31bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
- if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) {
+ codec = kzalloc(sizeof(*codec), GFP_KERNEL);
+ if (!codec) {
pci_disable_device(pci);
return -ENOMEM;
}
@@ -2293,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card,
/* M1533: southbridge */
codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL);
- if (! codec->pci_m1533) {
+ if (!codec->pci_m1533) {
snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
snd_ali_free(codec);
return -ENODEV;
}
/* M7101: power management */
codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL);
- if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
+ if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) {
snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
snd_ali_free(codec);
return -ENODEV;
}
snd_ali_printk("snd_device_new is called.\n");
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops);
+ if (err < 0) {
snd_ali_free(codec);
return err;
}
@@ -2315,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card,
snd_card_set_dev(card, &pci->dev);
/* initialise synth voices*/
- for (i = 0; i < ALI_CHANNELS; i++ ) {
+ for (i = 0; i < ALI_CHANNELS; i++)
codec->synth.voices[i].number = i;
- }
- if ((err = snd_ali_chip_init(codec)) < 0) {
+ err = snd_ali_chip_init(codec);
+ if (err < 0) {
snd_printk(KERN_ERR "ali create: chip init error.\n");
return err;
}
#ifdef CONFIG_PM
codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
- if (! codec->image)
+ if (!codec->image)
snd_printk(KERN_WARNING "can't allocate apm buffer\n");
#endif
@@ -2348,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
snd_ali_printk("probe ...\n");
card = snd_card_new(index, id, THIS_MODULE, 0);
- if (card == NULL)
+ if (!card)
return -ENOMEM;
- if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_ali_create(card, pci, pcm_channels, spdif, &codec);
+ if (err < 0)
+ goto error;
card->private_data = codec;
snd_ali_printk("mixer building ...\n");
- if ((err = snd_ali_mixer(codec)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_ali_mixer(codec);
+ if (err < 0)
+ goto error;
snd_ali_printk("pcm building ...\n");
- if ((err = snd_ali_build_pcms(codec)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_ali_build_pcms(codec);
+ if (err < 0)
+ goto error;
snd_ali_proc_init(codec);
@@ -2378,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
card->shortname, codec->port, codec->irq);
snd_ali_printk("register card.\n");
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_card_register(card);
+ if (err < 0)
+ goto error;
+
pci_set_drvdata(pci, card);
return 0;
+
+ error:
+ snd_card_free(card);
+ return err;
}
static void __devexit snd_ali_remove(struct pci_dev *pci)
diff --git a/sound/pci/au88x0/au88x0_sb.h b/sound/pci/au88x0/au88x0_sb.h
deleted file mode 100644
index 5a4d8fc2bbf..00000000000
--- a/sound/pci/au88x0/au88x0_sb.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/***************************************************************************
- * au88x0_sb.h
- *
- * Wed Oct 29 22:10:42 2003
- *
- ****************************************************************************/
-
-#ifdef CHIP_AU8820
-/* AU8820 starting @ 64KiB offset */
-#define SBEMU_BASE 0x10000
-#else
-/* AU8810? and AU8830 starting @ 164KiB offset */
-#define SBEMU_BASE 0x29000
-#endif
-
-#define FM_A_STATUS (SBEMU_BASE + 0x00) /* read */
-#define FM_A_ADDRESS (SBEMU_BASE + 0x00) /* write */
-#define FM_A_DATA (SBEMU_BASE + 0x04)
-#define FM_B_STATUS (SBEMU_BASE + 0x08)
-#define FM_B_ADDRESS (SBEMU_BASE + 0x08)
-#define FM_B_DATA (SBEMU_BASE + 0x0C)
-#define SB_MIXER_ADDR (SBEMU_BASE + 0x10)
-#define SB_MIXER_DATA (SBEMU_BASE + 0x14)
-#define SB_RESET (SBEMU_BASE + 0x18)
-#define SB_RESET_ALIAS (SBEMU_BASE + 0x1C)
-#define FM_STATUS2 (SBEMU_BASE + 0x20)
-#define FM_ADDR2 (SBEMU_BASE + 0x20)
-#define FM_DATA2 (SBEMU_BASE + 0x24)
-#define SB_DSP_READ (SBEMU_BASE + 0x28)
-#define SB_DSP_WRITE (SBEMU_BASE + 0x30)
-#define SB_DSP_WRITE_STATUS (SBEMU_BASE + 0x30) /* bit 7 */
-#define SB_DSP_READ_STATUS (SBEMU_BASE + 0x38) /* bit 7 */
-#define SB_LACR (SBEMU_BASE + 0x40) /* ? */
-#define SB_LADCR (SBEMU_BASE + 0x44) /* ? */
-#define SB_LAMR (SBEMU_BASE + 0x48) /* ? */
-#define SB_LARR (SBEMU_BASE + 0x4C) /* ? */
-#define SB_VERSION (SBEMU_BASE + 0x50)
-#define SB_CTRLSTAT (SBEMU_BASE + 0x54)
-#define SB_TIMERSTAT (SBEMU_BASE + 0x58)
-#define FM_RAM (SBEMU_BASE + 0x100) /* 0x40 ULONG */
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 43edd2839b5..36d3666a5b7 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
/*
* azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- * Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
+ * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de>
*
* Framework borrowed from Bart Hartgers's als4000.c.
* Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -52,6 +52,9 @@
* - full duplex 16bit playback/record at independent sampling rate
* - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
* - game port (legacy address support)
+ * - builtin 3D enhancement (said to be YAMAHA Ymersion)
+ * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
+ * features supported)
* - built-in General DirectX timer having a 20 bits counter
* with 1us resolution (see below!)
* - I2S serial port for external DAC
@@ -94,6 +97,10 @@
*
* BUGS
* - full-duplex might *still* be problematic, not fully tested recently
+ * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
+ * if you set PCM output switch to "pre 3D" instead of "post 3D".
+ * If this can't be set, then get a mixer application that Isn't Stupid (tm)
+ * (e.g. kmix, gamix) - unfortunately several are!!
*
* TODO
* - test MPU401 MIDI playback etc.
@@ -622,7 +629,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
return (nreg != oreg);
}
-static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
@@ -652,7 +659,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
- AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
+ AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
@@ -678,7 +685,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
#endif
};
-static const u16 __devinitdata snd_azf3328_init_values[][2] = {
+static u16 __devinitdata snd_azf3328_init_values[][2] = {
{ IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
{ IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
{ IDX_MIXER_BASSTREBLE, 0x0000 },
@@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream)
struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
snd_azf3328_dbgcallenter();
-
chip->playback_substream = NULL;
snd_azf3328_dbgcallleave();
return 0;
@@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit)
}
#endif
+#if DEBUG_MISC
static void
snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
{
-#if DEBUG_MISC
u16 tmp;
snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
@@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
for (tmp=0; tmp <= 0x01; tmp += 1)
snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
- for (tmp = 0; tmp <= 0x6E; tmp += 2)
- snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp));
-#endif
+ for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
+ snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp));
+
+ for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
+ snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp));
}
+#else
+static inline void
+snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}
+#endif
static int __devinit
snd_azf3328_create(struct snd_card *card,
@@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
#ifdef MODULE
printk(
-"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
-"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
+"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
+"azt3328: Hardware was completely undocumented, unfortunately.\n"
"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
1024000 / seqtimer_scaling, seqtimer_scaling);
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index b4f3e3cd006..679fa992e2b 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -106,8 +106,8 @@
#define IRQ_RECORDING 0x0002
#define IRQ_MPU401 0x0010
#define IRQ_TIMER 0x0020 /* DirectX timer */
- #define IRQ_UNKNOWN1 0x0040 /* probably unused */
- #define IRQ_UNKNOWN2 0x0080 /* probably unused */
+ #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */
+ #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */
#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
#define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index e9b029e1cd6..6523ba07db9 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
/* Viewcast Osprey 200 */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+ /* ATI TV-Wonder */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000),
/* Leadtek Winfast tv 2000xp delux */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
/* Voodoo TV 200 */
@@ -833,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
pci->device, pci->subsystem_vendor, pci->subsystem_device);
snd_printk(KERN_DEBUG "please mail id, board name, and, "
"if it works, the correct digital_rate option to "
- "<alsa-devel@lists.sf.net>\n");
+ "<alsa-devel@alsa-project.org>\n");
return 32000; /* default rate */
}
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ea6712b63c9..48f3f17c517 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
struct snd_ca0106_pcm *epcm;
int channel;
int result = 0;
- struct list_head *pos;
struct snd_pcm_substream *s;
u32 basic = 0;
u32 extended = 0;
@@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
running=0;
break;
}
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
runtime = s->runtime;
epcm = runtime->private_data;
channel = epcm->channel_id;
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 2ae539b195f..bef1f6d1859 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n");
snd_printk(KERN_ERR " broken or not working on your soundcard upon\n");
- snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n");
+ snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n");
return -EIO;
#endif
diff --git a/sound/pci/cs46xx/imgs/cwcemb80.h b/sound/pci/cs46xx/imgs/cwcemb80.h
deleted file mode 100644
index a64c6ff9983..00000000000
--- a/sound/pci/cs46xx/imgs/cwcemb80.h
+++ /dev/null
@@ -1,1607 +0,0 @@
-/* generated from cwcemb80.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcemb80_H__
-#define __HEADER_cwcemb80_H__
-
-static struct dsp_symbol_entry cwcemb80_symbols[] = {
- { 0x0000, "BEGINADDRESS",0x00 },
- { 0x8000, "EXECCHILD",0x03 },
- { 0x8001, "EXECCHILD_98",0x03 },
- { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
- { 0x8008, "EXECSIBLING",0x03 },
- { 0x800a, "EXECSIBLING_298",0x03 },
- { 0x800b, "EXECSIBLING_2IND1",0x03 },
- { 0x8010, "TIMINGMASTER",0x03 },
- { 0x804f, "S16_CODECINPUTTASK",0x03 },
- { 0x805e, "PCMSERIALINPUTTASK",0x03 },
- { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
- { 0x809a, "S16_MIX",0x03 },
- { 0x80bb, "S16_UPSRC",0x03 },
- { 0x813b, "MIX3_EXP",0x03 },
- { 0x8164, "DECIMATEBYPOW2",0x03 },
- { 0x8197, "VARIDECIMATE",0x03 },
- { 0x81f2, "_3DINPUTTASK",0x03 },
- { 0x820a, "_3DPRLGCINPTASK",0x03 },
- { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
- { 0x8242, "_3DOUTPUTTASK",0x03 },
- { 0x82c4, "HRTF_MORPH_TASK",0x03 },
- { 0x82c6, "WAIT4DATA",0x03 },
- { 0x82fa, "PROLOGIC",0x03 },
- { 0x8496, "DECORRELATOR",0x03 },
- { 0x84a4, "STEREO2MONO",0x03 },
- { 0x0070, "SPOSCB",0x02 },
- { 0x0105, "TASKTREETHREAD",0x03 },
- { 0x0136, "TASKTREEHEADERCODE",0x03 },
- { 0x013f, "FGTASKTREEHEADERCODE",0x03 },
- { 0x0163, "NULLALGORITHM",0x03 },
- { 0x0167, "HFGEXECCHILD",0x03 },
- { 0x0168, "HFGEXECCHILD_98",0x03 },
- { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 },
- { 0x016d, "HFGEXECSIBLING",0x03 },
- { 0x016f, "HFGEXECSIBLING_298",0x03 },
- { 0x0170, "HFGEXECSIBLING_2IND1",0x03 },
- { 0x0173, "S16_CODECOUTPUTTASK",0x03 },
- { 0x018e, "#CODE_END",0x00 },
-}; /* cwcemb80 symbols */
-
-static u32 cwcemb80_code[] = {
-/* BEGINADDRESS */
-/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
-/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
-/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
-/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
-/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
-/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
-/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
-/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
-/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
-/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
-/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
-/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
-/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
-/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
-/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
-/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
-/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
-/* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002,
-/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
-/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
-/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
-/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
-/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
-/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
-/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
-/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
-/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
-/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
-/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
-/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
-/* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004,
-/* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
-/* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640,
-/* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0,
-/* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0,
-/* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b,
-/* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44,
-/* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917,
-/* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880,
-/* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000,
-/* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000,
-/* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40,
-/* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
-/* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
-/* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0,
-/* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
-/* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
-/* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
-/* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
-/* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
-/* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
-/* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
-/* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
-/* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
-/* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
-/* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
-/* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
-/* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
-/* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
-/* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1,
-/* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000,
-/* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
-/* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700,
-/* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
-/* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
-/* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500,
-/* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
-/* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800,
-/* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500,
-/* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
-/* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00,
-/* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500,
-/* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
-/* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80,
-/* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500,
-/* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1,
-/* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380,
-/* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000,
-/* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
-/* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
-/* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
-/* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
-/* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
-/* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080,
-/* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540,
-/* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
-/* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40,
-/* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
-/* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
-/* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240,
-/* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
-/* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
-/* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c,
-/* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-/* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
-/* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
-/* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
-/* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
-/* 0104 */ 0x0000ba01,0x00000000,
-/* TASKTREETHREAD */
-/* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
-/* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
-/* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
-/* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa,
-/* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
-/* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000,
-/* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
-/* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008,
-/* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
-/* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0,
-/* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
-/* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009,
-/* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
-/* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000,
-/* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000,
-/* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008,
-/* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000,
-/* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000,
-/* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
-/* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000,
-/* 0135 */ 0x00000000,0x00000000,
-/* TASKTREEHEADERCODE */
-/* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
-/* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b,
-/* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-/* 013E */ 0x00042731,0x00001003,
-/* FGTASKTREEHEADERCODE */
-/* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a,
-/* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b,
-/* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140,
-/* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
-/* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
-/* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
-/* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
-/* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
-/* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
-/* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
-/* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
-/* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7,
-/* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004,
-/* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
-/* NULLALGORITHM */
-/* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
-/* HFGEXECCHILD */
-/* 0167 */ 0x00000000,0x000eba44,
-/* HFGEXECCHILD_98 */
-/* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-/* HFGEXECCHILD_PUSH1IND */
-/* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 016C */ 0x00006a88,0x000c75c4,
-/* HFGEXECSIBLING */
-/* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
-/* HFGEXECSIBLING_298 */
-/* 016F */ 0x00087401,0x000e4782,
-/* HFGEXECSIBLING_2IND1 */
-/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 0172 */ 0x00006a88,0x000c75c4,
-/* S16_CODECOUTPUTTASK */
-/* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
-/* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
-/* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
-/* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
-/* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c,
-/* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
-/* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
-/* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
-/* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
-/* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
-/* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
-/* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
-/* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
-/* 018D */ 0x00048f05,0x00000000
-};
-/* #CODE_END */
-
-static u32 cwcemb80_parameter[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000,
-/* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000,
-/* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000,
-/* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2,
-/* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000,
-/* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3,
-/* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d,
-/* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000,
-/* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a,
-/* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3,
-/* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000,
-/* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000,
-/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2,
-/* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff,
-/* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0,
-/* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000,
-/* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9,
-/* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff,
-/* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780,
-/* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000,
-/* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9,
-/* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff,
-/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1,
-/* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000,
-/* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000,
-/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000,
-/* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-/* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004,
-/* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610,
-/* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d,
-/* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
-/* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
-/* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d,
-/* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-/* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136,
-/* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000,
-/* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d,
-/* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
-/* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000,
-/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0694 */ 0x00000000,0x00000000,0x00000000
-}; /* #PARAMETER_END */
-
-static u32 cwcemb80_sample[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004
-}; /* #SAMPLE_END */
-
-
-static struct dsp_segment_desc cwcemb80_segments[] = {
- { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code },
- { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter },
- { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample },
-};
-
-static struct dsp_module_desc cwcemb80_module = {
- "cwcemb80",
- {
- 38,
- cwcemb80_symbols
- },
- 3,
- cwcemb80_segments,
-};
-
-#endif /* __HEADER_cwcemb80_H__ */
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index 8e7fe033270..87078d3a685 100644
--- a/sound/pci/echoaudio/darla20.c
+++ b/sound/pci/echoaudio/darla20.c
@@ -56,6 +56,8 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/darla20_dsp.fw");
+
#define FW_DARLA20_DSP 0
static const struct firmware card_fw[] = {
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index a13c623eb99..42b48f9d212 100644
--- a/sound/pci/echoaudio/darla24.c
+++ b/sound/pci/echoaudio/darla24.c
@@ -60,6 +60,8 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/darla24_dsp.fw");
+
#define FW_DARLA24_DSP 0
static const struct firmware card_fw[] = {
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index 8fb15823aca..8dbb7ac865c 100644
--- a/sound/pci/echoaudio/echo3g.c
+++ b/sound/pci/echoaudio/echo3g.c
@@ -68,6 +68,10 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/echo3g_dsp.fw");
+MODULE_FIRMWARE("ea/3g_asic.fw");
+
#define FW_361_LOADER 0
#define FW_ECHO3G_DSP 1
#define FW_3G_ASIC 2
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index e413da00759..f27b6a733b9 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct audiopipe *pipe = runtime->private_data;
int i, err;
u32 channelmask = 0;
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
for (i = 0; i < DSP_MAXPIPES; i++) {
if (s == chip->substream[i]) {
channelmask |= 1 << i;
diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c
index 9f439ea459f..52a93318957 100644
--- a/sound/pci/echoaudio/echoaudio_3g.c
+++ b/sound/pci/echoaudio/echoaudio_3g.c
@@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip)
chip->asic_code = &card_fw[FW_3G_ASIC];
- /* Now give the new ASIC a little time to set up */
- mdelay(2);
+ /* Now give the new ASIC some time to set up */
+ msleep(1000);
/* See if it worked */
box_type = check_asic_status(chip);
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index af4d32026e4..fee2d483173 100644
--- a/sound/pci/echoaudio/gina20.c
+++ b/sound/pci/echoaudio/gina20.c
@@ -60,6 +60,8 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/gina20_dsp.fw");
+
#define FW_GINA20_DSP 0
static const struct firmware card_fw[] = {
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index 9ff454a947e..d5eae470fe9 100644
--- a/sound/pci/echoaudio/gina24.c
+++ b/sound/pci/echoaudio/gina24.c
@@ -66,6 +66,12 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_301_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_361_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_301_asic.fw");
+MODULE_FIRMWARE("ea/gina24_361_asic.fw");
+
#define FW_361_LOADER 0
#define FW_GINA24_301_DSP 1
#define FW_GINA24_361_DSP 2
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index 37eb726fd03..40f601cd016 100644
--- a/sound/pci/echoaudio/indigo.c
+++ b/sound/pci/echoaudio/indigo.c
@@ -58,6 +58,9 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_dsp.fw");
+
#define FW_361_LOADER 0
#define FW_INDIGO_DSP 1
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index dc8b9182418..771c5383210 100644
--- a/sound/pci/echoaudio/indigodj.c
+++ b/sound/pci/echoaudio/indigodj.c
@@ -58,6 +58,9 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_dj_dsp.fw");
+
#define FW_361_LOADER 0
#define FW_INDIGO_DJ_DSP 1
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index eadf3263453..49c550defcf 100644
--- a/sound/pci/echoaudio/indigoio.c
+++ b/sound/pci/echoaudio/indigoio.c
@@ -59,6 +59,9 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_io_dsp.fw");
+
#define FW_361_LOADER 0
#define FW_INDIGO_IO_DSP 1
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index 6cede497579..8f5483a405a 100644
--- a/sound/pci/echoaudio/layla20.c
+++ b/sound/pci/echoaudio/layla20.c
@@ -66,6 +66,9 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/layla20_dsp.fw");
+MODULE_FIRMWARE("ea/layla20_asic.fw");
+
#define FW_LAYLA20_DSP 0
#define FW_LAYLA20_ASIC 1
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index 44f735426aa..0524667c02f 100644
--- a/sound/pci/echoaudio/layla24.c
+++ b/sound/pci/echoaudio/layla24.c
@@ -68,6 +68,12 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/layla24_dsp.fw");
+MODULE_FIRMWARE("ea/layla24_1_asic.fw");
+MODULE_FIRMWARE("ea/layla24_2A_asic.fw");
+MODULE_FIRMWARE("ea/layla24_2S_asic.fw");
+
#define FW_361_LOADER 0
#define FW_LAYLA24_DSP 1
#define FW_LAYLA24_1_ASIC 2
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index dc172d03ac3..893c7c20dd7 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -66,6 +66,9 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/mia_dsp.fw");
+
#define FW_361_LOADER 0
#define FW_MIA_DSP 1
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index c856ed50dd9..3a5d5b0020d 100644
--- a/sound/pci/echoaudio/mona.c
+++ b/sound/pci/echoaudio/mona.c
@@ -64,6 +64,15 @@
#include <asm/atomic.h>
#include "echoaudio.h"
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/mona_301_dsp.fw");
+MODULE_FIRMWARE("ea/mona_361_dsp.fw");
+MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw");
+MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw");
+MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw");
+MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw");
+MODULE_FIRMWARE("ea/mona_2_asic.fw");
+
#define FW_361_LOADER 0
#define FW_MONA_301_DSP 1
#define FW_MONA_361_DSP 2
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 80aa585eade..dbc805c33fc 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -49,6 +49,13 @@
#include "p17v.h"
+#define HANA_FILENAME "emu/hana.fw"
+#define DOCK_FILENAME "emu/audio_dock.fw"
+
+MODULE_FIRMWARE(HANA_FILENAME);
+MODULE_FIRMWARE(DOCK_FILENAME);
+
+
/*************************************************************************
* EMU10K1 init / done
*************************************************************************/
@@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
int tmp,tmp2;
int reg;
int err;
- const char *hana_filename = "emu/hana.fw";
- const char *dock_filename = "emu/audio_dock.fw";
snd_printk(KERN_INFO "emu1010: Special config.\n");
/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
@@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
return -ENODEV;
}
snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
- if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) {
- snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename);
+ 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;
}
@@ -938,7 +943,7 @@ 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 ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) {
+ if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
return err;
}
snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
@@ -1216,6 +1221,15 @@ static struct snd_emu_chip_details emu_chip_details[] = {
.spi_dac = 1,
.i2c_adc = 1,
.spk71 = 1} ,
+ {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
+ .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",
+ .id = "EMU1010",
+ .emu10k2_chip = 1,
+ .ca0108_chip = 1,
+ .ca_cardbus_chip = 1,
+ .spi_dac = 1,
+ .i2c_adc = 1,
+ .spk71 = 1} ,
{.vendor = 0x1102, .device = 0x0008,
.driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
.id = "Audigy2",
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 465f8d50532..7ee19c63c2c 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
struct snd_emu10k1_pcm *epcm;
int channel;
int result = 0;
- struct list_head *pos;
struct snd_pcm_substream *s;
u32 basic = 0;
u32 inte = 0;
@@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
running = 0;
break;
}
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
runtime = s->runtime;
epcm = runtime->private_data;
channel = substream->pcm->device-emu->p16v_device_offset;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 425b167522d..6a0ddcf0088 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
{
unsigned int what = 0;
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == ensoniq->playback1_substream) {
what |= ES_P1_PAUSE;
snd_pcm_trigger_done(s, substream);
@@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_STOP:
{
unsigned int what = 0;
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == ensoniq->playback1_substream) {
what |= ES_DAC1_EN;
snd_pcm_trigger_done(s, substream);
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index dc84c189b05..2faf009076b 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
runtime->hw = snd_es1968_playback;
runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
calc_available_memory_size(chip);
-#if 0
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- 1024);
-#endif
+
spin_lock_irq(&chip->substream_lock);
list_add(&es->list, &chip->substream_list);
spin_unlock_irq(&chip->substream_lock);
@@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
runtime->hw = snd_es1968_capture;
runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
-#if 0
- snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
- 1024);
-#endif
+ snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
+
spin_lock_irq(&chip->substream_lock);
list_add(&es->list, &chip->substream_list);
spin_unlock_irq(&chip->substream_lock);
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 60d7b05a204..b2484bbdcc1 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,5 +1,8 @@
snd-hda-intel-objs := hda_intel.o
-snd-hda-codec-objs := hda_codec.o \
+# since snd-hda-intel is the only driver using hda-codec,
+# merge it into a single module although it was originally
+# designed to be individual modules
+snd-hda-intel-objs += hda_codec.o \
hda_generic.o \
patch_realtek.o \
patch_cmedia.o \
@@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \
patch_conexant.o \
patch_via.o
ifdef CONFIG_PROC_FS
-snd-hda-codec-objs += hda_proc.o
+snd-hda-intel-objs += hda_proc.o
endif
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o
+obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8f34fb44798..14649d54b49 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -24,7 +24,6 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pci.h>
-#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include "hda_codec.h"
@@ -34,11 +33,6 @@
#include "hda_local.h"
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec");
-MODULE_LICENSE("GPL");
-
-
/*
* vendor / preset table
*/
@@ -77,12 +71,13 @@ static struct hda_vendor_id hda_vendor_ids[] = {
*
* Returns the obtained response value, or -1 for an error.
*/
-unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct,
+unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
+ int direct,
unsigned int verb, unsigned int parm)
{
unsigned int res;
mutex_lock(&codec->bus->cmd_mutex);
- if (! codec->bus->ops.command(codec, nid, direct, verb, parm))
+ if (!codec->bus->ops.command(codec, nid, direct, verb, parm))
res = codec->bus->ops.get_response(codec);
else
res = (unsigned int)-1;
@@ -90,8 +85,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire
return res;
}
-EXPORT_SYMBOL(snd_hda_codec_read);
-
/**
* snd_hda_codec_write - send a single command without waiting for response
* @codec: the HDA codec
@@ -114,8 +107,6 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
return err;
}
-EXPORT_SYMBOL(snd_hda_codec_write);
-
/**
* snd_hda_sequence_write - sequence writes
* @codec: the HDA codec
@@ -130,8 +121,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
}
-EXPORT_SYMBOL(snd_hda_sequence_write);
-
/**
* snd_hda_get_sub_nodes - get the range of sub nodes
* @codec: the HDA codec
@@ -141,7 +130,8 @@ EXPORT_SYMBOL(snd_hda_sequence_write);
* Parse the NID and store the start NID of its sub-nodes.
* Returns the number of sub-nodes.
*/
-int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id)
+int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
+ hda_nid_t *start_id)
{
unsigned int parm;
@@ -150,8 +140,6 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta
return (int)(parm & 0x7fff);
}
-EXPORT_SYMBOL(snd_hda_get_sub_nodes);
-
/**
* snd_hda_get_connections - get connection list
* @codec: the HDA codec
@@ -187,12 +175,13 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
conn_len = parm & AC_CLIST_LENGTH;
mask = (1 << (shift-1)) - 1;
- if (! conn_len)
+ if (!conn_len)
return 0; /* no connection */
if (conn_len == 1) {
/* single connection */
- parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0);
+ parm = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONNECT_LIST, 0);
conn_list[0] = parm & mask;
return 1;
}
@@ -207,18 +196,21 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
if (i % num_elems == 0)
parm = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_CONNECT_LIST, i);
- range_val = !! (parm & (1 << (shift-1))); /* ranges */
+ range_val = !!(parm & (1 << (shift-1))); /* ranges */
val = parm & mask;
parm >>= shift;
if (range_val) {
/* ranges between the previous and this one */
- if (! prev_nid || prev_nid >= val) {
- snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val);
+ if (!prev_nid || prev_nid >= val) {
+ snd_printk(KERN_WARNING "hda_codec: "
+ "invalid dep_range_val %x:%x\n",
+ prev_nid, val);
continue;
}
for (n = prev_nid + 1; n <= val; n++) {
if (conns >= max_conns) {
- snd_printk(KERN_ERR "Too many connections\n");
+ snd_printk(KERN_ERR
+ "Too many connections\n");
return -EINVAL;
}
conn_list[conns++] = n;
@@ -253,7 +245,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
struct hda_bus_unsolicited *unsol;
unsigned int wp;
- if ((unsol = bus->unsol) == NULL)
+ unsol = bus->unsol;
+ if (!unsol)
return 0;
wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;
@@ -268,8 +261,6 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
return 0;
}
-EXPORT_SYMBOL(snd_hda_queue_unsol_event);
-
/*
* process queueud unsolicited events
*/
@@ -287,7 +278,7 @@ static void process_unsol_events(struct work_struct *work)
rp <<= 1;
res = unsol->queue[rp];
caddr = unsol->queue[rp + 1];
- if (! (caddr & (1 << 4))) /* no unsolicited event? */
+ if (!(caddr & (1 << 4))) /* no unsolicited event? */
continue;
codec = bus->caddr_tbl[caddr & 0x0f];
if (codec && codec->patch_ops.unsol_event)
@@ -298,7 +289,7 @@ static void process_unsol_events(struct work_struct *work)
/*
* initialize unsolicited queue
*/
-static int init_unsol_queue(struct hda_bus *bus)
+static int __devinit init_unsol_queue(struct hda_bus *bus)
{
struct hda_bus_unsolicited *unsol;
@@ -306,8 +297,9 @@ static int init_unsol_queue(struct hda_bus *bus)
return 0;
unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
- if (! unsol) {
- snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
+ if (!unsol) {
+ snd_printk(KERN_ERR "hda_codec: "
+ "can't allocate unsolicited queue\n");
return -ENOMEM;
}
INIT_WORK(&unsol->work, process_unsol_events);
@@ -323,16 +315,15 @@ static void snd_hda_codec_free(struct hda_codec *codec);
static int snd_hda_bus_free(struct hda_bus *bus)
{
- struct list_head *p, *n;
+ struct hda_codec *codec, *n;
- if (! bus)
+ if (!bus)
return 0;
if (bus->unsol) {
flush_scheduled_work();
kfree(bus->unsol);
}
- list_for_each_safe(p, n, &bus->codec_list) {
- struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
snd_hda_codec_free(codec);
}
if (bus->ops.private_free)
@@ -355,8 +346,9 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
*
* Returns 0 if successful, or a negative error code.
*/
-int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
- struct hda_bus **busp)
+int __devinit snd_hda_bus_new(struct snd_card *card,
+ const struct hda_bus_template *temp,
+ struct hda_bus **busp)
{
struct hda_bus *bus;
int err;
@@ -385,7 +377,8 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
mutex_init(&bus->cmd_mutex);
INIT_LIST_HEAD(&bus->codec_list);
- if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
+ if (err < 0) {
snd_hda_bus_free(bus);
return err;
}
@@ -394,22 +387,24 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
return 0;
}
-EXPORT_SYMBOL(snd_hda_bus_new);
-
/*
* find a matching codec preset
*/
-static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec)
+static const struct hda_codec_preset __devinit *
+find_codec_preset(struct hda_codec *codec)
{
const struct hda_codec_preset **tbl, *preset;
+ if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic"))
+ return NULL; /* use the generic parser */
+
for (tbl = hda_preset_tables; *tbl; tbl++) {
for (preset = *tbl; preset->id; preset++) {
u32 mask = preset->mask;
- if (! mask)
+ if (!mask)
mask = ~0;
if (preset->id == (codec->vendor_id & mask) &&
- (! preset->rev ||
+ (!preset->rev ||
preset->rev == codec->revision_id))
return preset;
}
@@ -434,27 +429,30 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
break;
}
}
- if (! vendor) {
+ if (!vendor) {
sprintf(tmp, "Generic %04x", vendor_id);
vendor = tmp;
}
if (codec->preset && codec->preset->name)
snprintf(name, namelen, "%s %s", vendor, codec->preset->name);
else
- snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff);
+ snprintf(name, namelen, "%s ID %x", vendor,
+ codec->vendor_id & 0xffff);
}
/*
* look for an AFG and MFG nodes
*/
-static void setup_fg_nodes(struct hda_codec *codec)
+static void __devinit setup_fg_nodes(struct hda_codec *codec)
{
int i, total_nodes;
hda_nid_t nid;
total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
for (i = 0; i < total_nodes; i++, nid++) {
- switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) {
+ unsigned int func;
+ func = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE);
+ switch (func & 0xff) {
case AC_GRP_AUDIO_FUNCTION:
codec->afg = nid;
break;
@@ -478,7 +476,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,
&codec->start_nid);
codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);
- if (! codec->wcaps)
+ if (!codec->wcaps)
return -ENOMEM;
nid = codec->start_nid;
for (i = 0; i < codec->num_nodes; i++, nid++)
@@ -493,7 +491,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
*/
static void snd_hda_codec_free(struct hda_codec *codec)
{
- if (! codec)
+ if (!codec)
return;
list_del(&codec->list);
codec->bus->caddr_tbl[codec->addr] = NULL;
@@ -514,8 +512,8 @@ static void init_amp_hash(struct hda_codec *codec);
*
* Returns 0 if successful, or a negative error code.
*/
-int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
- struct hda_codec **codecp)
+int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+ struct hda_codec **codecp)
{
struct hda_codec *codec;
char component[13];
@@ -525,7 +523,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL);
if (bus->caddr_tbl[codec_addr]) {
- snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr);
+ snd_printk(KERN_ERR "hda_codec: "
+ "address 0x%x is already occupied\n", codec_addr);
return -EBUSY;
}
@@ -543,18 +542,21 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
list_add_tail(&codec->list, &bus->codec_list);
bus->caddr_tbl[codec_addr] = codec;
- codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID);
+ codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+ AC_PAR_VENDOR_ID);
if (codec->vendor_id == -1)
/* read again, hopefully the access method was corrected
* in the last read...
*/
codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
AC_PAR_VENDOR_ID);
- codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
- codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
+ codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+ AC_PAR_SUBSYSTEM_ID);
+ codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+ AC_PAR_REV_ID);
setup_fg_nodes(codec);
- if (! codec->afg && ! codec->mfg) {
+ if (!codec->afg && !codec->mfg) {
snd_printdd("hda_codec: no AFG or MFG node found\n");
snd_hda_codec_free(codec);
return -ENODEV;
@@ -566,15 +568,16 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
return -ENOMEM;
}
- if (! codec->subsystem_id) {
+ if (!codec->subsystem_id) {
hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
- codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_SUBSYSTEM_ID,
- 0);
+ codec->subsystem_id =
+ snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_SUBSYSTEM_ID, 0);
}
codec->preset = find_codec_preset(codec);
- if (! *bus->card->mixername)
+ /* audio codec should override the mixer name */
+ if (codec->afg || !*bus->card->mixername)
snd_hda_get_codec_name(codec, bus->card->mixername,
sizeof(bus->card->mixername));
@@ -600,8 +603,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
return 0;
}
-EXPORT_SYMBOL(snd_hda_codec_new);
-
/**
* snd_hda_codec_setup_stream - set up the codec for streaming
* @codec: the CODEC to set up
@@ -610,13 +611,15 @@ EXPORT_SYMBOL(snd_hda_codec_new);
* @channel_id: channel id to pass, zero based.
* @format: stream format.
*/
-void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag,
+void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
+ u32 stream_tag,
int channel_id, int format)
{
- if (! nid)
+ if (!nid)
return;
- snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
+ snd_printdd("hda_codec_setup_stream: "
+ "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
nid, stream_tag, channel_id, format);
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
(stream_tag << 4) | channel_id);
@@ -624,8 +627,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
}
-EXPORT_SYMBOL(snd_hda_codec_setup_stream);
-
/*
* amp access functions
*/
@@ -636,7 +637,7 @@ EXPORT_SYMBOL(snd_hda_codec_setup_stream);
#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
/* initialize the hash table */
-static void init_amp_hash(struct hda_codec *codec)
+static void __devinit init_amp_hash(struct hda_codec *codec)
{
memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));
codec->num_amp_entries = 0;
@@ -662,15 +663,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
if (codec->num_amp_entries >= codec->amp_info_size) {
/* reallocate the array */
int new_size = codec->amp_info_size + 64;
- struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
- GFP_KERNEL);
- if (! new_info) {
- snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n");
+ struct hda_amp_info *new_info;
+ new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
+ GFP_KERNEL);
+ if (!new_info) {
+ snd_printk(KERN_ERR "hda_codec: "
+ "can't malloc amp_info\n");
return NULL;
}
if (codec->amp_info) {
memcpy(new_info, codec->amp_info,
- codec->amp_info_size * sizeof(struct hda_amp_info));
+ codec->amp_info_size *
+ sizeof(struct hda_amp_info));
kfree(codec->amp_info);
}
codec->amp_info_size = new_size;
@@ -691,15 +695,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
*/
static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
{
- struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
+ struct hda_amp_info *info;
- if (! info)
+ info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
+ if (!info)
return 0;
- if (! (info->status & INFO_AMP_CAPS)) {
- if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
+ if (!(info->status & INFO_AMP_CAPS)) {
+ if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
nid = codec->afg;
- info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ?
- AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
+ info->amp_caps = snd_hda_param_read(codec, nid,
+ direction == HDA_OUTPUT ?
+ AC_PAR_AMP_OUT_CAP :
+ AC_PAR_AMP_IN_CAP);
info->status |= INFO_AMP_CAPS;
}
return info->amp_caps;
@@ -709,8 +716,9 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
* read the current volume to info
* if the cache exists, read the cache value.
*/
-static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
- hda_nid_t nid, int ch, int direction, int index)
+static unsigned int get_vol_mute(struct hda_codec *codec,
+ struct hda_amp_info *info, hda_nid_t nid,
+ int ch, int direction, int index)
{
u32 val, parm;
@@ -720,7 +728,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i
parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
parm |= index;
- val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm);
+ val = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_AMP_GAIN_MUTE, parm);
info->vol[ch] = val & 0xff;
info->status |= INFO_AMP_VOL(ch);
return info->vol[ch];
@@ -730,7 +739,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i
* write the current volume in info to the h/w and update the cache
*/
static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
- hda_nid_t nid, int ch, int direction, int index, int val)
+ hda_nid_t nid, int ch, int direction, int index,
+ int val)
{
u32 parm;
@@ -748,8 +758,9 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int index)
{
- struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
- if (! info)
+ struct hda_amp_info *info;
+ info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
+ if (!info)
return 0;
return get_vol_mute(codec, info, nid, ch, direction, index);
}
@@ -760,13 +771,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int idx, int mask, int val)
{
- struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
+ struct hda_amp_info *info;
- if (! info)
+ info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
+ if (!info)
return 0;
val &= mask;
val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
- if (info->vol[ch] == val && ! codec->in_resume)
+ if (info->vol[ch] == val && !codec->in_resume)
return 0;
put_vol_mute(codec, info, nid, ch, direction, idx, val);
return 1;
@@ -783,7 +795,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
/* volume */
-int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
u16 nid = get_amp_nid(kcontrol);
@@ -792,9 +805,11 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
u32 caps;
caps = query_amp_caps(codec, nid, dir);
- caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */
- if (! caps) {
- printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid);
+ /* num steps */
+ caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
+ if (!caps) {
+ printk(KERN_WARNING "hda_codec: "
+ "num_steps = 0 for NID=0x%x\n", nid);
return -EINVAL;
}
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -804,7 +819,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
return 0;
}
-int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = get_amp_nid(kcontrol);
@@ -820,7 +836,8 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
return 0;
}
-int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = get_amp_nid(kcontrol);
@@ -852,7 +869,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
if (size < 4 * sizeof(unsigned int))
return -ENOMEM;
caps = query_amp_caps(codec, nid, dir);
- val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25;
+ val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
+ val2 = (val2 + 1) * 25;
val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
val1 = ((int)val1) * ((int)val2);
if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
@@ -867,7 +885,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
}
/* switch */
-int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
int chs = get_amp_channels(kcontrol);
@@ -878,7 +897,8 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
return 0;
}
-int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = get_amp_nid(kcontrol);
@@ -888,13 +908,16 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
long *valp = ucontrol->value.integer.value;
if (chs & 1)
- *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1;
+ *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
+ 0x80) ? 0 : 1;
if (chs & 2)
- *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1;
+ *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
+ 0x80) ? 0 : 1;
return 0;
}
-int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = get_amp_nid(kcontrol);
@@ -925,7 +948,8 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
#define AMP_VAL_IDX_SHIFT 19
#define AMP_VAL_IDX_MASK (0x0f<<19)
-int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned long pval;
@@ -940,7 +964,8 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
return err;
}
-int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned long pval;
@@ -950,7 +975,8 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
pval = kcontrol->private_value;
indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
for (i = 0; i < indices; i++) {
- kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
+ kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) |
+ (i << AMP_VAL_IDX_SHIFT);
err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
if (err < 0)
break;
@@ -965,14 +991,16 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
* SPDIF out controls
*/
-static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
return 0;
}
-static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
IEC958_AES0_NONAUDIO |
@@ -983,7 +1011,8 @@ static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl
return 0;
}
-static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
IEC958_AES0_NONAUDIO |
@@ -991,7 +1020,8 @@ static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl
return 0;
}
-static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -1011,19 +1041,21 @@ static unsigned short convert_from_spdif_status(unsigned int sbits)
unsigned short val = 0;
if (sbits & IEC958_AES0_PROFESSIONAL)
- val |= 1 << 6;
+ val |= AC_DIG1_PROFESSIONAL;
if (sbits & IEC958_AES0_NONAUDIO)
- val |= 1 << 5;
+ val |= AC_DIG1_NONAUDIO;
if (sbits & IEC958_AES0_PROFESSIONAL) {
- if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
- val |= 1 << 3;
+ if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
+ IEC958_AES0_PRO_EMPHASIS_5015)
+ val |= AC_DIG1_EMPHASIS;
} else {
- if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015)
- val |= 1 << 3;
- if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
- val |= 1 << 4;
+ if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
+ IEC958_AES0_CON_EMPHASIS_5015)
+ val |= AC_DIG1_EMPHASIS;
+ if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
+ val |= AC_DIG1_COPYRIGHT;
if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
- val |= 1 << 7;
+ val |= AC_DIG1_LEVEL;
val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
}
return val;
@@ -1035,26 +1067,27 @@ static unsigned int convert_to_spdif_status(unsigned short val)
{
unsigned int sbits = 0;
- if (val & (1 << 5))
+ if (val & AC_DIG1_NONAUDIO)
sbits |= IEC958_AES0_NONAUDIO;
- if (val & (1 << 6))
+ if (val & AC_DIG1_PROFESSIONAL)
sbits |= IEC958_AES0_PROFESSIONAL;
if (sbits & IEC958_AES0_PROFESSIONAL) {
- if (sbits & (1 << 3))
+ if (sbits & AC_DIG1_EMPHASIS)
sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
} else {
- if (val & (1 << 3))
+ if (val & AC_DIG1_EMPHASIS)
sbits |= IEC958_AES0_CON_EMPHASIS_5015;
- if (! (val & (1 << 4)))
+ if (!(val & AC_DIG1_COPYRIGHT))
sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
- if (val & (1 << 7))
+ if (val & AC_DIG1_LEVEL)
sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
sbits |= val & (0x7f << 8);
}
return sbits;
}
-static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = kcontrol->private_value;
@@ -1072,15 +1105,18 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c
codec->spdif_ctls = val;
if (change || codec->in_resume) {
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ val & 0xff);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2,
+ val >> 8);
}
mutex_unlock(&codec->spdif_mutex);
return change;
}
-static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
@@ -1089,15 +1125,17 @@ static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct s
return 0;
}
-static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = codec->spdif_ctls & 1;
+ ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE;
return 0;
}
-static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = kcontrol->private_value;
@@ -1105,16 +1143,21 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn
int change;
mutex_lock(&codec->spdif_mutex);
- val = codec->spdif_ctls & ~1;
+ val = codec->spdif_ctls & ~AC_DIG1_ENABLE;
if (ucontrol->value.integer.value[0])
- val |= 1;
+ val |= AC_DIG1_ENABLE;
change = codec->spdif_ctls != val;
if (change || codec->in_resume) {
codec->spdif_ctls = val;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
- AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ val & 0xff);
+ /* unmute amp switch (if any) */
+ if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
+ (val & AC_DIG1_ENABLE))
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
+ AC_AMP_SET_OUTPUT);
}
mutex_unlock(&codec->spdif_mutex);
return change;
@@ -1162,7 +1205,8 @@ static struct snd_kcontrol_new dig_mixes[] = {
*
* Returns 0 if successful, or a negative error code.
*/
-int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
+int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
+ hda_nid_t nid)
{
int err;
struct snd_kcontrol *kctl;
@@ -1171,10 +1215,12 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
kctl = snd_ctl_new1(dig_mix, codec);
kctl->private_value = nid;
- if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+ err = snd_ctl_add(codec->bus->card, kctl);
+ if (err < 0)
return err;
}
- codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
+ codec->spdif_ctls =
+ snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
return 0;
}
@@ -1185,7 +1231,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
#define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info
-static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -1193,7 +1240,8 @@ static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd
return 0;
}
-static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = kcontrol->private_value;
@@ -1204,13 +1252,15 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd
change = codec->spdif_in_enable != val;
if (change || codec->in_resume) {
codec->spdif_in_enable = val;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ val);
}
mutex_unlock(&codec->spdif_mutex);
return change;
}
-static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = kcontrol->private_value;
@@ -1254,7 +1304,8 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
*
* Returns 0 if successful, or a negative error code.
*/
-int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
+int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec,
+ hda_nid_t nid)
{
int err;
struct snd_kcontrol *kctl;
@@ -1263,10 +1314,13 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
kctl = snd_ctl_new1(dig_mix, codec);
kctl->private_value = nid;
- if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+ err = snd_ctl_add(codec->bus->card, kctl);
+ if (err < 0)
return err;
}
- codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1;
+ codec->spdif_in_enable =
+ snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) &
+ AC_DIG1_ENABLE;
return 0;
}
@@ -1304,15 +1358,14 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
*
* Returns 0 if successful, otherwise a negative error code.
*/
-int snd_hda_build_controls(struct hda_bus *bus)
+int __devinit snd_hda_build_controls(struct hda_bus *bus)
{
- struct list_head *p;
+ struct hda_codec *codec;
/* build controls */
- list_for_each(p, &bus->codec_list) {
- struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &bus->codec_list, list) {
int err;
- if (! codec->patch_ops.build_controls)
+ if (!codec->patch_ops.build_controls)
continue;
err = codec->patch_ops.build_controls(codec);
if (err < 0)
@@ -1320,13 +1373,12 @@ int snd_hda_build_controls(struct hda_bus *bus)
}
/* initialize */
- list_for_each(p, &bus->codec_list) {
- struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &bus->codec_list, list) {
int err;
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D0);
- if (! codec->patch_ops.init)
+ if (!codec->patch_ops.init)
continue;
err = codec->patch_ops.init(codec);
if (err < 0)
@@ -1335,8 +1387,6 @@ int snd_hda_build_controls(struct hda_bus *bus)
return 0;
}
-EXPORT_SYMBOL(snd_hda_build_controls);
-
/*
* stream formats
*/
@@ -1361,6 +1411,11 @@ static struct hda_rate_tbl rate_bits[] = {
{ 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
{ 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
{ 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
+#define AC_PAR_PCM_RATE_BITS 11
+ /* up to bits 10, 384kHZ isn't supported properly */
+
+ /* not autodetected value */
+ { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
{ 0 } /* terminator */
};
@@ -1389,7 +1444,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
val = rate_bits[i].hda_fmt;
break;
}
- if (! rate_bits[i].hz) {
+ if (!rate_bits[i].hz) {
snd_printdd("invalid rate %d\n", rate);
return 0;
}
@@ -1414,15 +1469,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
val |= 0x20;
break;
default:
- snd_printdd("invalid format width %d\n", snd_pcm_format_width(format));
+ snd_printdd("invalid format width %d\n",
+ snd_pcm_format_width(format));
return 0;
}
return val;
}
-EXPORT_SYMBOL(snd_hda_calc_stream_format);
-
/**
* snd_hda_query_supported_pcm - query the supported PCM rates and formats
* @codec: the HDA codec
@@ -1449,12 +1503,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
if (val == -1)
return -EIO;
}
- if (! val)
+ if (!val)
val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
if (ratesp) {
u32 rates = 0;
- for (i = 0; rate_bits[i].hz; i++) {
+ for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
if (val & (1 << i))
rates |= rate_bits[i].alsa_bits;
}
@@ -1470,8 +1524,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
if (streams == -1)
return -EIO;
- if (! streams) {
- streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
+ if (!streams) {
+ streams = snd_hda_param_read(codec, codec->afg,
+ AC_PAR_STREAM);
if (streams == -1)
return -EIO;
}
@@ -1495,7 +1550,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
bps = 24;
else if (val & AC_SUPPCM_BITS_20)
bps = 20;
- } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) {
+ } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
+ AC_SUPPCM_BITS_32)) {
formats |= SNDRV_PCM_FMTBIT_S32_LE;
if (val & AC_SUPPCM_BITS_32)
bps = 32;
@@ -1505,10 +1561,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
bps = 20;
}
}
- else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */
+ else if (streams == AC_SUPFMT_FLOAT32) {
+ /* should be exclusive */
formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
bps = 32;
- } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */
+ } else if (streams == AC_SUPFMT_AC3) {
+ /* should be exclusive */
/* temporary hack: we have still no proper support
* for the direct AC3 stream...
*/
@@ -1525,7 +1583,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
}
/**
- * snd_hda_is_supported_format - check whether the given node supports the format val
+ * snd_hda_is_supported_format - check whether the given node supports
+ * the format val
*
* Returns 1 if supported, 0 if not.
*/
@@ -1541,50 +1600,50 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
if (val == -1)
return 0;
}
- if (! val) {
+ if (!val) {
val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
if (val == -1)
return 0;
}
rate = format & 0xff00;
- for (i = 0; rate_bits[i].hz; i++)
+ for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
if (rate_bits[i].hda_fmt == rate) {
if (val & (1 << i))
break;
return 0;
}
- if (! rate_bits[i].hz)
+ if (i >= AC_PAR_PCM_RATE_BITS)
return 0;
stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
if (stream == -1)
return 0;
- if (! stream && nid != codec->afg)
+ if (!stream && nid != codec->afg)
stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
- if (! stream || stream == -1)
+ if (!stream || stream == -1)
return 0;
if (stream & AC_SUPFMT_PCM) {
switch (format & 0xf0) {
case 0x00:
- if (! (val & AC_SUPPCM_BITS_8))
+ if (!(val & AC_SUPPCM_BITS_8))
return 0;
break;
case 0x10:
- if (! (val & AC_SUPPCM_BITS_16))
+ if (!(val & AC_SUPPCM_BITS_16))
return 0;
break;
case 0x20:
- if (! (val & AC_SUPPCM_BITS_20))
+ if (!(val & AC_SUPPCM_BITS_20))
return 0;
break;
case 0x30:
- if (! (val & AC_SUPPCM_BITS_24))
+ if (!(val & AC_SUPPCM_BITS_24))
return 0;
break;
case 0x40:
- if (! (val & AC_SUPPCM_BITS_32))
+ if (!(val & AC_SUPPCM_BITS_32))
return 0;
break;
default:
@@ -1625,15 +1684,15 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
return 0;
}
-static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info)
+static int __devinit set_pcm_default_values(struct hda_codec *codec,
+ struct hda_pcm_stream *info)
{
- if (info->nid) {
- /* query support PCM information from the given NID */
- if (! info->rates || ! info->formats)
- snd_hda_query_supported_pcm(codec, info->nid,
- info->rates ? NULL : &info->rates,
- info->formats ? NULL : &info->formats,
- info->maxbps ? NULL : &info->maxbps);
+ /* query support PCM information from the given NID */
+ if (info->nid && (!info->rates || !info->formats)) {
+ snd_hda_query_supported_pcm(codec, info->nid,
+ info->rates ? NULL : &info->rates,
+ info->formats ? NULL : &info->formats,
+ info->maxbps ? NULL : &info->maxbps);
}
if (info->ops.open == NULL)
info->ops.open = hda_pcm_default_open_close;
@@ -1676,15 +1735,14 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream
*
* This function returns 0 if successfull, or a negative error code.
*/
-int snd_hda_build_pcms(struct hda_bus *bus)
+int __devinit snd_hda_build_pcms(struct hda_bus *bus)
{
- struct list_head *p;
+ struct hda_codec *codec;
- list_for_each(p, &bus->codec_list) {
- struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &bus->codec_list, list) {
unsigned int pcm, s;
int err;
- if (! codec->patch_ops.build_pcms)
+ if (!codec->patch_ops.build_pcms)
continue;
err = codec->patch_ops.build_pcms(codec);
if (err < 0)
@@ -1693,7 +1751,7 @@ int snd_hda_build_pcms(struct hda_bus *bus)
for (s = 0; s < 2; s++) {
struct hda_pcm_stream *info;
info = &codec->pcm_info[pcm].stream[s];
- if (! info->substreams)
+ if (!info->substreams)
continue;
err = set_pcm_default_values(codec, info);
if (err < 0)
@@ -1704,8 +1762,6 @@ int snd_hda_build_pcms(struct hda_bus *bus)
return 0;
}
-EXPORT_SYMBOL(snd_hda_build_pcms);
-
/**
* snd_hda_check_board_config - compare the current codec with the config table
* @codec: the HDA codec
@@ -1719,9 +1775,9 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
*
* If no entries are matching, the function returns a negative value.
*/
-int snd_hda_check_board_config(struct hda_codec *codec,
- int num_configs, const char **models,
- const struct snd_pci_quirk *tbl)
+int __devinit snd_hda_check_board_config(struct hda_codec *codec,
+ int num_configs, const char **models,
+ const struct snd_pci_quirk *tbl)
{
if (codec->bus->modelname && models) {
int i;
@@ -1771,24 +1827,26 @@ int snd_hda_check_board_config(struct hda_codec *codec,
*
* Returns 0 if successful, or a negative error code.
*/
-int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
+int __devinit snd_hda_add_new_ctls(struct hda_codec *codec,
+ struct snd_kcontrol_new *knew)
{
int err;
for (; knew->name; knew++) {
struct snd_kcontrol *kctl;
kctl = snd_ctl_new1(knew, codec);
- if (! kctl)
+ if (!kctl)
return -ENOMEM;
err = snd_ctl_add(codec->bus->card, kctl);
if (err < 0) {
- if (! codec->addr)
+ if (!codec->addr)
return err;
kctl = snd_ctl_new1(knew, codec);
- if (! kctl)
+ if (!kctl)
return -ENOMEM;
kctl->id.device = codec->addr;
- if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+ err = snd_ctl_add(codec->bus->card, kctl);
+ if (err < 0)
return err;
}
}
@@ -1799,8 +1857,10 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
/*
* Channel mode helper
*/
-int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo,
- const struct hda_channel_mode *chmode, int num_chmodes)
+int snd_hda_ch_mode_info(struct hda_codec *codec,
+ struct snd_ctl_elem_info *uinfo,
+ const struct hda_channel_mode *chmode,
+ int num_chmodes)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
@@ -1812,8 +1872,10 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinf
return 0;
}
-int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_get(struct hda_codec *codec,
+ struct snd_ctl_elem_value *ucontrol,
+ const struct hda_channel_mode *chmode,
+ int num_chmodes,
int max_channels)
{
int i;
@@ -1827,15 +1889,17 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucon
return 0;
}
-int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_put(struct hda_codec *codec,
+ struct snd_ctl_elem_value *ucontrol,
+ const struct hda_channel_mode *chmode,
+ int num_chmodes,
int *max_channelsp)
{
unsigned int mode;
mode = ucontrol->value.enumerated.item[0];
snd_assert(mode < num_chmodes, return -EINVAL);
- if (*max_channelsp == chmode[mode].channels && ! codec->in_resume)
+ if (*max_channelsp == chmode[mode].channels && !codec->in_resume)
return 0;
/* change the current channel setting */
*max_channelsp = chmode[mode].channels;
@@ -1847,7 +1911,8 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucon
/*
* input MUX helper
*/
-int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo)
+int snd_hda_input_mux_info(const struct hda_input_mux *imux,
+ struct snd_ctl_elem_info *uinfo)
{
unsigned int index;
@@ -1861,8 +1926,10 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem
return 0;
}
-int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
- struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
+int snd_hda_input_mux_put(struct hda_codec *codec,
+ const struct hda_input_mux *imux,
+ struct snd_ctl_elem_value *ucontrol,
+ hda_nid_t nid,
unsigned int *cur_val)
{
unsigned int idx;
@@ -1870,7 +1937,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && ! codec->in_resume)
+ if (*cur_val == idx && !codec->in_resume)
return 0;
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
imux->items[idx].index);
@@ -1883,25 +1950,53 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
* Multi-channel / digital-out PCM helper functions
*/
+/* setup SPDIF output stream */
+static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
+ unsigned int stream_tag, unsigned int format)
+{
+ /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
+ if (codec->spdif_ctls & AC_DIG1_ENABLE)
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+ snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
+ /* turn on again (if needed) */
+ if (codec->spdif_ctls & AC_DIG1_ENABLE)
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ codec->spdif_ctls & 0xff);
+}
+
/*
* open the digital out in the exclusive mode
*/
-int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_dig_open(struct hda_codec *codec,
+ struct hda_multi_out *mout)
{
mutex_lock(&codec->spdif_mutex);
- if (mout->dig_out_used) {
- mutex_unlock(&codec->spdif_mutex);
- return -EBUSY; /* already being used */
- }
+ if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
+ /* already opened as analog dup; reset it once */
+ snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
mout->dig_out_used = HDA_DIG_EXCLUSIVE;
mutex_unlock(&codec->spdif_mutex);
return 0;
}
+int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
+ struct hda_multi_out *mout,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ mutex_lock(&codec->spdif_mutex);
+ setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
+ mutex_unlock(&codec->spdif_mutex);
+ return 0;
+}
+
/*
* release the digital out
*/
-int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_dig_close(struct hda_codec *codec,
+ struct hda_multi_out *mout)
{
mutex_lock(&codec->spdif_mutex);
mout->dig_out_used = 0;
@@ -1912,7 +2007,8 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *m
/*
* set up more restrictions for analog out
*/
-int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_open(struct hda_codec *codec,
+ struct hda_multi_out *mout,
struct snd_pcm_substream *substream)
{
substream->runtime->hw.channels_max = mout->max_channels;
@@ -1924,7 +2020,8 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out
* set up the i/o for analog out
* when the digital out is available, copy the front out to digital out, too.
*/
-int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
+ struct hda_multi_out *mout,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
@@ -1936,24 +2033,27 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
mutex_lock(&codec->spdif_mutex);
if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
if (chs == 2 &&
- snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
- ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
+ snd_hda_is_supported_format(codec, mout->dig_out_nid,
+ format) &&
+ !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
mout->dig_out_used = HDA_DIG_ANALOG_DUP;
- /* setup digital receiver */
- snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
- stream_tag, 0, format);
+ setup_dig_out_stream(codec, mout->dig_out_nid,
+ stream_tag, format);
} else {
mout->dig_out_used = 0;
- snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
+ snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
+ 0, 0, 0);
}
}
mutex_unlock(&codec->spdif_mutex);
/* front */
- snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
+ snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
+ 0, format);
if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
/* headphone out will just decode front left/right (stereo) */
- snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
+ snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
+ 0, format);
/* extra outputs copied from front */
for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
if (mout->extra_out_nid[i])
@@ -1964,11 +2064,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
/* surrounds */
for (i = 1; i < mout->num_dacs; i++) {
if (chs >= (i + 1) * 2) /* independent out */
- snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
- format);
+ snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+ i * 2, format);
else /* copy front */
- snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,
- format);
+ snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+ 0, format);
}
return 0;
}
@@ -1976,7 +2076,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
/*
* clean up the setting for analog out
*/
-int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
+ struct hda_multi_out *mout)
{
hda_nid_t *nids = mout->dac_nids;
int i;
@@ -2003,7 +2104,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o
* Helper for automatic ping configuration
*/
-static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
+static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
{
for (; *list; list++)
if (*list == nid)
@@ -2011,6 +2112,32 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
return 0;
}
+
+/*
+ * Sort an associated group of pins according to their sequence numbers.
+ */
+static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
+ int num_pins)
+{
+ int i, j;
+ short seq;
+ hda_nid_t nid;
+
+ for (i = 0; i < num_pins; i++) {
+ for (j = i + 1; j < num_pins; j++) {
+ if (sequences[i] > sequences[j]) {
+ seq = sequences[i];
+ sequences[i] = sequences[j];
+ sequences[j] = seq;
+ nid = pins[i];
+ pins[i] = pins[j];
+ pins[j] = nid;
+ }
+ }
+ }
+}
+
+
/*
* Parse all pin widgets and store the useful pin nids to cfg
*
@@ -2028,22 +2155,27 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
* The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
* respectively.
*/
-int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
- hda_nid_t *ignore_nids)
+int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec,
+ struct auto_pin_cfg *cfg,
+ hda_nid_t *ignore_nids)
{
hda_nid_t nid, nid_start;
- int i, j, nodes;
- short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)];
+ int nodes;
+ short seq, assoc_line_out, assoc_speaker;
+ short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
+ short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
memset(cfg, 0, sizeof(*cfg));
- memset(sequences, 0, sizeof(sequences));
- assoc_line_out = 0;
+ memset(sequences_line_out, 0, sizeof(sequences_line_out));
+ memset(sequences_speaker, 0, sizeof(sequences_speaker));
+ assoc_line_out = assoc_speaker = 0;
nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
for (nid = nid_start; nid < nodes + nid_start; nid++) {
unsigned int wid_caps = get_wcaps(codec, nid);
- unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+ unsigned int wid_type =
+ (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
unsigned int def_conf;
short assoc, loc;
@@ -2054,7 +2186,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
if (ignore_nids && is_in_nid_list(nid, ignore_nids))
continue;
- def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+ def_conf = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONFIG_DEFAULT, 0);
if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
continue;
loc = get_defcfg_location(def_conf);
@@ -2062,22 +2195,31 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
case AC_JACK_LINE_OUT:
seq = get_defcfg_sequence(def_conf);
assoc = get_defcfg_association(def_conf);
- if (! assoc)
+ if (!assoc)
continue;
- if (! assoc_line_out)
+ if (!assoc_line_out)
assoc_line_out = assoc;
else if (assoc_line_out != assoc)
continue;
if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
continue;
cfg->line_out_pins[cfg->line_outs] = nid;
- sequences[cfg->line_outs] = seq;
+ sequences_line_out[cfg->line_outs] = seq;
cfg->line_outs++;
break;
case AC_JACK_SPEAKER:
+ seq = get_defcfg_sequence(def_conf);
+ assoc = get_defcfg_association(def_conf);
+ if (! assoc)
+ continue;
+ if (! assoc_speaker)
+ assoc_speaker = assoc;
+ else if (assoc_speaker != assoc)
+ continue;
if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
continue;
cfg->speaker_pins[cfg->speaker_outs] = nid;
+ sequences_speaker[cfg->speaker_outs] = seq;
cfg->speaker_outs++;
break;
case AC_JACK_HP_OUT:
@@ -2123,34 +2265,45 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
}
/* sort by sequence */
- for (i = 0; i < cfg->line_outs; i++)
- for (j = i + 1; j < cfg->line_outs; j++)
- if (sequences[i] > sequences[j]) {
- seq = sequences[i];
- sequences[i] = sequences[j];
- sequences[j] = seq;
- nid = cfg->line_out_pins[i];
- cfg->line_out_pins[i] = cfg->line_out_pins[j];
- cfg->line_out_pins[j] = nid;
- }
+ sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
+ cfg->line_outs);
+ sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
+ cfg->speaker_outs);
+
+ /*
+ * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
+ * as a primary output
+ */
+ if (!cfg->line_outs) {
+ if (cfg->speaker_outs) {
+ cfg->line_outs = cfg->speaker_outs;
+ memcpy(cfg->line_out_pins, cfg->speaker_pins,
+ sizeof(cfg->speaker_pins));
+ cfg->speaker_outs = 0;
+ memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
+ cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
+ } else if (cfg->hp_outs) {
+ cfg->line_outs = cfg->hp_outs;
+ memcpy(cfg->line_out_pins, cfg->hp_pins,
+ sizeof(cfg->hp_pins));
+ cfg->hp_outs = 0;
+ memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
+ cfg->line_out_type = AUTO_PIN_HP_OUT;
+ }
+ }
/* Reorder the surround channels
* ALSA sequence is front/surr/clfe/side
* HDA sequence is:
* 4-ch: front/surr => OK as it is
* 6-ch: front/clfe/surr
- * 8-ch: front/clfe/side/surr
+ * 8-ch: front/clfe/rear/side|fc
*/
switch (cfg->line_outs) {
case 3:
- nid = cfg->line_out_pins[1];
- cfg->line_out_pins[1] = cfg->line_out_pins[2];
- cfg->line_out_pins[2] = nid;
- break;
case 4:
nid = cfg->line_out_pins[1];
- cfg->line_out_pins[1] = cfg->line_out_pins[3];
- cfg->line_out_pins[3] = cfg->line_out_pins[2];
+ cfg->line_out_pins[1] = cfg->line_out_pins[2];
cfg->line_out_pins[2] = nid;
break;
}
@@ -2179,26 +2332,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
cfg->input_pins[AUTO_PIN_CD],
cfg->input_pins[AUTO_PIN_AUX]);
- /*
- * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
- * as a primary output
- */
- if (! cfg->line_outs) {
- if (cfg->speaker_outs) {
- cfg->line_outs = cfg->speaker_outs;
- memcpy(cfg->line_out_pins, cfg->speaker_pins,
- sizeof(cfg->speaker_pins));
- cfg->speaker_outs = 0;
- memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
- } else if (cfg->hp_outs) {
- cfg->line_outs = cfg->hp_outs;
- memcpy(cfg->line_out_pins, cfg->hp_pins,
- sizeof(cfg->hp_pins));
- cfg->hp_outs = 0;
- memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
- }
- }
-
return 0;
}
@@ -2222,11 +2355,10 @@ const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
*/
int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
{
- struct list_head *p;
+ struct hda_codec *codec;
/* FIXME: should handle power widget capabilities */
- list_for_each(p, &bus->codec_list) {
- struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &bus->codec_list, list) {
if (codec->patch_ops.suspend)
codec->patch_ops.suspend(codec, state);
hda_set_power_state(codec,
@@ -2236,8 +2368,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
return 0;
}
-EXPORT_SYMBOL(snd_hda_suspend);
-
/**
* snd_hda_resume - resume the codecs
* @bus: the HDA bus
@@ -2247,10 +2377,9 @@ EXPORT_SYMBOL(snd_hda_suspend);
*/
int snd_hda_resume(struct hda_bus *bus)
{
- struct list_head *p;
+ struct hda_codec *codec;
- list_for_each(p, &bus->codec_list) {
- struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &bus->codec_list, list) {
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D0);
@@ -2260,8 +2389,6 @@ int snd_hda_resume(struct hda_bus *bus)
return 0;
}
-EXPORT_SYMBOL(snd_hda_resume);
-
/**
* snd_hda_resume_ctls - resume controls in the new control list
* @codec: the HDA codec
@@ -2276,7 +2403,7 @@ int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
struct snd_ctl_elem_value *val;
val = kmalloc(sizeof(*val), GFP_KERNEL);
- if (! val)
+ if (!val)
return -ENOMEM;
codec->in_resume = 1;
for (; knew->name; knew++) {
@@ -2320,19 +2447,3 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec)
return snd_hda_resume_ctls(codec, dig_in_ctls);
}
#endif
-
-/*
- * INIT part
- */
-
-static int __init alsa_hda_init(void)
-{
- return 0;
-}
-
-static void __exit alsa_hda_exit(void)
-{
-}
-
-module_init(alsa_hda_init)
-module_exit(alsa_hda_exit)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index c12bc4e8840..56c26e7ccdf 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -233,7 +233,7 @@ enum {
*/
/* Amp gain/mute */
-#define AC_AMP_MUTE (1<<8)
+#define AC_AMP_MUTE (1<<7)
#define AC_AMP_GAIN (0x7f)
#define AC_AMP_GET_INDEX (0xf<<0)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 1e5ff0cd370..000287f7da4 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
return -ENOMEM;
}
}
- memcpy(node->conn_list, conn_list, nconns);
+ memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
node->nconns = nconns;
node->wid_caps = get_wcaps(codec, nid);
node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 1672cace1ae..2fa281cbef9 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
"{ATI, SB600},"
"{ATI, RS600},"
"{ATI, RS690},"
+ "{ATI, RS780},"
+ "{ATI, R600},"
"{VIA, VT8251},"
"{VIA, VT8237A},"
"{SiS, SIS966},"
@@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define RIRB_INT_MASK 0x05
/* STATESTS int mask: SD2,SD1,SD0 */
+#define AZX_MAX_CODECS 3
#define STATESTS_INT_MASK 0x07
/* SD_CTL bits */
@@ -978,7 +981,7 @@ static unsigned int azx_max_codecs[] __devinitdata = {
static int __devinit azx_codec_create(struct azx *chip, const char *model)
{
struct hda_bus_template bus_temp;
- int c, codecs, err;
+ int c, codecs, audio_codecs, err;
memset(&bus_temp, 0, sizeof(bus_temp));
bus_temp.private_data = chip;
@@ -990,16 +993,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
return err;
- codecs = 0;
- for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
+ codecs = audio_codecs = 0;
+ for (c = 0; c < AZX_MAX_CODECS; c++) {
if ((chip->codec_mask & (1 << c)) & probe_mask) {
- err = snd_hda_codec_new(chip->bus, c, NULL);
+ struct hda_codec *codec;
+ err = snd_hda_codec_new(chip->bus, c, &codec);
if (err < 0)
continue;
codecs++;
+ if (codec->afg)
+ audio_codecs++;
}
}
- if (! codecs) {
+ if (!audio_codecs) {
+ /* probe additional slots if no codec is found */
+ for (; c < azx_max_codecs[chip->driver_type]; c++) {
+ if ((chip->codec_mask & (1 << c)) & probe_mask) {
+ err = snd_hda_codec_new(chip->bus, c, NULL);
+ if (err < 0)
+ continue;
+ codecs++;
+ }
+ }
+ }
+ if (!codecs) {
snd_printk(KERN_ERR SFX "no codecs initialized\n");
return -ENXIO;
}
@@ -1518,7 +1535,7 @@ static int azx_dev_free(struct snd_device *device)
/*
* white/black-listing for position_fix
*/
-static const struct snd_pci_quirk position_fix_list[] __devinitdata = {
+static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
{}
};
@@ -1758,6 +1775,8 @@ static struct pci_device_id azx_ids[] = {
{ 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
{ 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
{ 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
+ { 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */
+ { 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */
{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 39718d6cdad..be12b8814c3 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -148,6 +148,11 @@ struct hda_multi_out {
int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
+int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
+ struct hda_multi_out *mout,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream);
int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
struct snd_pcm_substream *substream);
int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
@@ -217,6 +222,12 @@ enum {
AUTO_PIN_LAST
};
+enum {
+ AUTO_PIN_LINE_OUT,
+ AUTO_PIN_SPEAKER_OUT,
+ AUTO_PIN_HP_OUT
+};
+
extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
struct auto_pin_cfg {
@@ -225,6 +236,7 @@ struct auto_pin_cfg {
int speaker_outs;
hda_nid_t speaker_pins[5];
int hp_outs;
+ int line_out_type; /* AUTO_PIN_XXX_OUT */
hda_nid_t hp_pins[5];
hda_nid_t input_pins[AUTO_PIN_LAST];
hda_nid_t dig_out_pin;
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index f94f1f22889..0e1a879663f 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct ad198x_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+ format, substream);
+}
+
/*
* Analog capture
*/
@@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
.nid = 0, /* fill later */
.ops = {
.open = ad198x_dig_playback_pcm_open,
- .close = ad198x_dig_playback_pcm_close
+ .close = ad198x_dig_playback_pcm_close,
+ .prepare = ad198x_dig_playback_pcm_prepare
},
};
@@ -739,41 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = {
{ } /* end */
};
-/* additional verbs for 3-stack model */
-static struct hda_verb ad1986a_3st_init_verbs[] = {
- /* Mic and line-in selectors */
- {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
- {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
- { } /* end */
-};
-
static struct hda_verb ad1986a_ch2_init[] = {
/* Surround out -> Line In */
- { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+ /* Line-in selectors */
+ { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
/* CLFE -> Mic in */
- { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+ { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+ /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
+ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
{ } /* end */
};
static struct hda_verb ad1986a_ch4_init[] = {
/* Surround out -> Surround */
- { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
/* CLFE -> Mic in */
- { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
- { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+ { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
{ } /* end */
};
static struct hda_verb ad1986a_ch6_init[] = {
/* Surround out -> Surround out */
- { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
/* CLFE -> CLFE */
- { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
- { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+ { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
{ } /* end */
};
@@ -828,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
+ SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
@@ -882,9 +889,8 @@ static int patch_ad1986a(struct hda_codec *codec)
case AD1986A_3STACK:
spec->num_mixers = 2;
spec->mixers[1] = ad1986a_3st_mixers;
- spec->num_init_verbs = 3;
- spec->init_verbs[1] = ad1986a_3st_init_verbs;
- spec->init_verbs[2] = ad1986a_ch2_init;
+ spec->num_init_verbs = 2;
+ spec->init_verbs[1] = ad1986a_ch2_init;
spec->channel_mode = ad1986a_modes;
spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
spec->need_dac_fix = 1;
@@ -1892,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
if (sel > 0) {
- sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0);
- if (sel <= 3)
+ sel = snd_hda_codec_read(codec, 0x0b, 0,
+ AC_VERB_GET_CONNECT_SEL, 0);
+ if (sel < 3)
sel++;
else
sel = 0;
@@ -1906,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- unsigned int sel;
+ unsigned int val, sel;
int change;
+ val = ucontrol->value.enumerated.item[0];
sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
- if (! ucontrol->value.enumerated.item[0]) {
+ if (!val) {
change = sel != 0;
- if (change)
- snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0);
+ if (change || codec->in_resume)
+ snd_hda_codec_write(codec, 0x02, 0,
+ AC_VERB_SET_CONNECT_SEL, 0);
} else {
change = sel == 0;
- if (change)
- snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1);
- sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1;
- change |= sel == ucontrol->value.enumerated.item[0];
- if (change)
- snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL,
- ucontrol->value.enumerated.item[0] - 1);
+ if (change || codec->in_resume)
+ snd_hda_codec_write(codec, 0x02, 0,
+ AC_VERB_SET_CONNECT_SEL, 1);
+ sel = snd_hda_codec_read(codec, 0x0b, 0,
+ AC_VERB_GET_CONNECT_SEL, 0) + 1;
+ change |= sel != val;
+ if (change || codec->in_resume)
+ snd_hda_codec_write(codec, 0x0b, 0,
+ AC_VERB_SET_CONNECT_SEL, val - 1);
}
return change;
}
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 831469d3a92..f8eb4c90f80 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct atihdmi_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+ format, substream);
+}
+
static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
.substreams = 1,
.channels_min = 2,
@@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
.nid = 0x2, /* NID to query formats and rates and setup streams */
.ops = {
.open = atihdmi_dig_playback_pcm_open,
- .close = atihdmi_dig_playback_pcm_close
+ .close = atihdmi_dig_playback_pcm_close,
+ .prepare = atihdmi_dig_playback_pcm_prepare
},
};
@@ -160,6 +172,7 @@ 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 = 0x1002791a, .name = "ATI RS690 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/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 5b9d3a31a1a..3c722e667bc 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct cmi_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+ format, substream);
+}
+
/*
* Analog capture
*/
@@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = {
/* NID is set in cmi9880_build_pcms */
.ops = {
.open = cmi9880_dig_playback_pcm_open,
- .close = cmi9880_dig_playback_pcm_close
+ .close = cmi9880_dig_playback_pcm_close,
+ .prepare = cmi9880_dig_playback_pcm_prepare
},
};
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 46e93c6b9a4..a5a4b2bddf2 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct conexant_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+ stream_tag,
+ format, substream);
+}
+
/*
* Analog capture
*/
@@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = {
.nid = 0, /* fill later */
.ops = {
.open = conexant_dig_playback_pcm_open,
- .close = conexant_dig_playback_pcm_close
+ .close = conexant_dig_playback_pcm_close,
+ .prepare = conexant_dig_playback_pcm_prepare
},
};
@@ -452,115 +465,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
.put = conexant_ch_mode_put, \
.private_value = nid | (dir<<16) }
-static int cxt_gpio_data_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 cxt_gpio_data_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = kcontrol->private_value & 0xffff;
- unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
- long *valp = ucontrol->value.integer.value;
- unsigned int val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_DATA, 0x00);
-
- *valp = (val & mask) != 0;
- return 0;
-}
-
-static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = kcontrol->private_value & 0xffff;
- unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
- long val = *ucontrol->value.integer.value;
- unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_GPIO_DATA,
- 0x00);
- unsigned int old_data = gpio_data;
-
- /* Set/unset the masked GPIO bit(s) as needed */
- if (val == 0)
- gpio_data &= ~mask;
- else
- gpio_data |= mask;
- if (gpio_data == old_data && !codec->in_resume)
- return 0;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
- return 1;
-}
-
-#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = cxt_gpio_data_info, \
- .get = cxt_gpio_data_get, \
- .put = cxt_gpio_data_put, \
- .private_value = nid | (mask<<16) }
-#if 0
-static int cxt_spdif_ctrl_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 cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = kcontrol->private_value & 0xffff;
- unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
- long *valp = ucontrol->value.integer.value;
- unsigned int val = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_DIGI_CONVERT, 0x00);
-
- *valp = (val & mask) != 0;
- return 0;
-}
-
-static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- hda_nid_t nid = kcontrol->private_value & 0xffff;
- unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
- long val = *ucontrol->value.integer.value;
- unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_DIGI_CONVERT,
- 0x00);
- unsigned int old_data = ctrl_data;
-
- /* Set/unset the masked control bit(s) as needed */
- if (val == 0)
- ctrl_data &= ~mask;
- else
- ctrl_data |= mask;
- if (ctrl_data == old_data && !codec->in_resume)
- return 0;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- ctrl_data);
- return 1;
-}
-
-#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
- { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
- .info = cxt_spdif_ctrl_info, \
- .get = cxt_spdif_ctrl_get, \
- .put = cxt_spdif_ctrl_put, \
- .private_value = nid | (mask<<16) }
-#endif
#endif /* CONFIG_SND_DEBUG */
/* Conexant 5045 specific */
@@ -599,6 +503,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
+
bits = spec->cur_eapd ? 0 : 0x80;
snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits);
@@ -624,6 +529,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol,
return change;
}
+/* toggle input of built-in and mic jack appropriately */
+static void cxt5045_hp_automic(struct hda_codec *codec)
+{
+ static struct hda_verb mic_jack_on[] = {
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+ {}
+ };
+ static struct hda_verb mic_jack_off[] = {
+ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+ {}
+ };
+ unsigned int present;
+
+ present = snd_hda_codec_read(codec, 0x12, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ if (present)
+ snd_hda_sequence_write(codec, mic_jack_on);
+ else
+ snd_hda_sequence_write(codec, mic_jack_off);
+}
+
/* mute internal speaker if HP is plugged */
static void cxt5045_hp_automute(struct hda_codec *codec)
@@ -634,7 +562,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec)
spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
+ bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
}
@@ -648,6 +576,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
case CONEXANT_HP_EVENT:
cxt5045_hp_automute(codec);
break;
+ case CONEXANT_MIC_EVENT:
+ cxt5045_hp_automic(codec);
+ break;
+
}
}
@@ -659,12 +591,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
.get = conexant_mux_enum_get,
.put = conexant_mux_enum_put
},
- HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT),
+ HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Volume",
@@ -688,7 +618,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
static struct hda_verb cxt5045_init_verbs[] = {
/* Line in, Mic */
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
- {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
/* HP, Amp */
{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
{0x17, AC_VERB_SET_CONNECT_SEL,0x01},
@@ -701,18 +631,29 @@ static struct hda_verb cxt5045_init_verbs[] = {
{0x17, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04},
/* Record selector: Int mic */
- {0x1a, AC_VERB_SET_CONNECT_SEL,0x0},
+ {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
/* SPDIF route: PCM */
{ 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
- /* pin sensing on HP and Mic jacks */
- {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
/* EAPD */
{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */
{ } /* end */
};
+
+static struct hda_verb cxt5045_hp_sense_init_verbs[] = {
+ /* pin sensing on HP jack */
+ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
+ { } /* end */
+};
+
+static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
+ /* pin sensing on HP jack */
+ {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
+ { } /* end */
+};
+
#ifdef CONFIG_SND_DEBUG
/* Test configuration for debugging, modelled after the ALC260 test
* configuration.
@@ -733,6 +674,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
/* Output controls */
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
/* Modes for retasking pin widgets */
CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
@@ -742,25 +687,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
/* Loopback mixer controls */
- HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT),
- HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT),
- HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT),
- HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT),
- HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT),
- HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT),
- HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT),
- HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT),
-
- HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT),
- HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT),
+
+ HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
+ HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
+ HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Input Source",
@@ -768,14 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
.get = conexant_mux_enum_get,
.put = conexant_mux_enum_put,
},
-
{ } /* end */
};
static struct hda_verb cxt5045_test_init_verbs[] = {
+ /* Set connections */
+ { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
+ { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
+ { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
/* Enable retasking pins as output, initially without power amp */
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
- {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
/* Disable digital (SPDIF) pins initially, but users can enable
* them via a mixer switch. In the case of SPDIF-out, this initverb
@@ -804,6 +744,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = {
* pin)
*/
{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
/* Mute all inputs to mixer widget (even unconnected ones) */
{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
@@ -827,7 +768,8 @@ static int cxt5045_init(struct hda_codec *codec)
enum {
- CXT5045_LAPTOP, /* Laptops w/ EAPD support */
+ CXT5045_LAPTOP, /* Laptops w/ EAPD support */
+ CXT5045_FUJITSU, /* Laptops w/ EAPD support */
#ifdef CONFIG_SND_DEBUG
CXT5045_TEST,
#endif
@@ -836,6 +778,7 @@ enum {
static const char *cxt5045_models[CXT5045_MODELS] = {
[CXT5045_LAPTOP] = "laptop",
+ [CXT5045_FUJITSU] = "fujitsu",
#ifdef CONFIG_SND_DEBUG
[CXT5045_TEST] = "test",
#endif
@@ -844,7 +787,11 @@ static const char *cxt5045_models[CXT5045_MODELS] = {
static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP),
SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP),
- SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP),
+ 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(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU),
+ SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP),
{}
};
@@ -877,16 +824,23 @@ static int patch_cxt5045(struct hda_codec *codec)
codec->patch_ops = conexant_patch_ops;
- codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
cxt5045_models,
cxt5045_cfg_tbl);
switch (board_config) {
case CXT5045_LAPTOP:
+ codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
+ spec->input_mux = &cxt5045_capture_source;
+ spec->num_init_verbs = 2;
+ spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
+ spec->mixers[0] = cxt5045_mixers;
+ codec->patch_ops.init = cxt5045_init;
+ break;
+ case CXT5045_FUJITSU:
spec->input_mux = &cxt5045_capture_source;
spec->num_init_verbs = 2;
- spec->init_verbs[1] = cxt5045_init_verbs;
+ spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
spec->mixers[0] = cxt5045_mixers;
codec->patch_ops.init = cxt5045_init;
break;
@@ -913,10 +867,9 @@ static struct hda_channel_mode cxt5047_modes[1] = {
};
static struct hda_input_mux cxt5047_capture_source = {
- .num_items = 2,
+ .num_items = 1,
.items = {
- { "ExtMic", 0x0 },
- { "IntMic", 0x1 },
+ { "Mic", 0x2 },
}
};
@@ -1009,7 +962,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec)
};
unsigned int present;
- present = snd_hda_codec_read(codec, 0x08, 0,
+ present = snd_hda_codec_read(codec, 0x15, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
if (present)
snd_hda_sequence_write(codec, mic_jack_on);
@@ -1033,37 +986,20 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
}
static struct snd_kcontrol_new cxt5047_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = conexant_mux_enum_info,
- .get = conexant_mux_enum_get,
- .put = conexant_mux_enum_put
- },
HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT),
HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = cxt5047_hp_master_vol_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = cxt_eapd_info,
- .get = cxt_eapd_get,
- .put = cxt5047_hp_master_sw_put,
- .private_value = 0x13,
- },
+ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT),
{}
};
@@ -1133,18 +1069,19 @@ static struct hda_verb cxt5047_init_verbs[] = {
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
- /* HP, Amp, Speaker */
- {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
- {0x1A, AC_VERB_SET_CONNECT_SEL,0x00},
- {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
- {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
+ /* HP, Speaker */
+ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
+ {0x13, AC_VERB_SET_CONNECT_SEL,0x1},
{0x1d, AC_VERB_SET_CONNECT_SEL,0x0},
- /* Record selector: Front mic */
+ /* Record selector: Mic */
{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
+ {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
+ {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
+ AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
+ {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
+ AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
/* SPDIF route: PCM */
{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
/* Enable unsolicited events */
@@ -1161,8 +1098,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
/* Speaker routing */
{0x1d, AC_VERB_SET_CONNECT_SEL,0x1},
- /* Change default to ExtMic for recording */
- {0x1a, AC_VERB_SET_CONNECT_SEL,0x2},
{}
};
@@ -1172,7 +1107,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = {
{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
/* Record selector: Ext Mic */
{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
- {0x1a, AC_VERB_SET_CONNECT_SEL,0x02},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
/* Speaker routing */
@@ -1242,14 +1176,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
.get = conexant_mux_enum_get,
.put = conexant_mux_enum_put,
},
- /* Controls for GPIO pins, assuming they exist and are configured
- * as outputs
- */
- CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
- CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
- CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
- CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
-
{ } /* end */
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index fba3cb11bc2..a4ede27af02 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -74,6 +74,8 @@ enum {
ALC260_HP_3013,
ALC260_FUJITSU_S702X,
ALC260_ACER,
+ ALC260_WILL,
+ ALC260_REPLACER_672V,
#ifdef CONFIG_SND_DEBUG
ALC260_TEST,
#endif
@@ -115,15 +117,28 @@ enum {
ALC861VD_3ST,
ALC861VD_3ST_DIG,
ALC861VD_6ST_DIG,
+ ALC861VD_LENOVO,
ALC861VD_AUTO,
ALC861VD_MODEL_LAST,
};
+/* ALC662 models */
+enum {
+ ALC662_3ST_2ch_DIG,
+ ALC662_3ST_6ch_DIG,
+ ALC662_3ST_6ch,
+ ALC662_5ST_DIG,
+ ALC662_LENOVO_101E,
+ ALC662_AUTO,
+ ALC662_MODEL_LAST,
+};
+
/* ALC882 models */
enum {
ALC882_3ST_DIG,
ALC882_6ST_DIG,
ALC882_ARIMA,
+ ALC882_W2JC,
ALC882_AUTO,
ALC885_MACPRO,
ALC882_MODEL_LAST,
@@ -141,6 +156,7 @@ enum {
ALC883_ACER,
ALC883_MEDION,
ALC883_LAPTOP_EAPD,
+ ALC883_LENOVO_101E_2ch,
ALC883_AUTO,
ALC883_MODEL_LAST,
};
@@ -163,7 +179,7 @@ struct alc_spec {
struct hda_pcm_stream *stream_analog_playback;
struct hda_pcm_stream *stream_analog_capture;
- char *stream_name_digital; /* digital PCM stream */
+ char *stream_name_digital; /* digital PCM stream */
struct hda_pcm_stream *stream_digital_playback;
struct hda_pcm_stream *stream_digital_capture;
@@ -401,7 +417,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
AC_VERB_GET_PIN_WIDGET_CONTROL,
0x00);
- if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
+ if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
val = alc_pin_mode_min(dir);
change = pinctl != alc_pin_mode_values[val];
@@ -460,7 +476,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
-}
+}
+
static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -520,7 +537,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
-}
+}
+
static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -592,7 +610,7 @@ static void setup_preset(struct alc_spec *spec,
spec->multiout.hp_nid = preset->hp_nid;
spec->num_mux_defs = preset->num_mux_defs;
- if (! spec->num_mux_defs)
+ if (!spec->num_mux_defs)
spec->num_mux_defs = 1;
spec->input_mux = preset->input_mux;
@@ -604,6 +622,90 @@ static void setup_preset(struct alc_spec *spec,
spec->init_hook = preset->init_hook;
}
+/* Enable GPIO mask and set output */
+static struct hda_verb alc_gpio1_init_verbs[] = {
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+ { }
+};
+
+static struct hda_verb alc_gpio2_init_verbs[] = {
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
+ { }
+};
+
+static struct hda_verb alc_gpio3_init_verbs[] = {
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+ { }
+};
+
+/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
+ * 31 ~ 16 : Manufacture ID
+ * 15 ~ 8 : SKU ID
+ * 7 ~ 0 : Assembly ID
+ * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
+ */
+static void alc_subsystem_id(struct hda_codec *codec,
+ unsigned int porta, unsigned int porte,
+ unsigned int portd)
+{
+ unsigned int ass, tmp;
+
+ ass = codec->subsystem_id;
+ if (!(ass & 1))
+ return;
+
+ /* Override */
+ tmp = (ass & 0x38) >> 3; /* external Amp control */
+ switch (tmp) {
+ case 1:
+ snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
+ break;
+ case 3:
+ snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
+ break;
+ case 7:
+ snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
+ break;
+ case 5:
+ switch (codec->vendor_id) {
+ case 0x10ec0862:
+ case 0x10ec0660:
+ case 0x10ec0662:
+ case 0x10ec0267:
+ case 0x10ec0268:
+ snd_hda_codec_write(codec, 0x14, 0,
+ AC_VERB_SET_EAPD_BTLENABLE, 2);
+ snd_hda_codec_write(codec, 0x15, 0,
+ AC_VERB_SET_EAPD_BTLENABLE, 2);
+ return;
+ }
+ case 6:
+ if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */
+ hda_nid_t port = 0;
+ tmp = (ass & 0x1800) >> 11;
+ switch (tmp) {
+ case 0: port = porta; break;
+ case 1: port = porte; break;
+ case 2: port = portd; break;
+ }
+ if (port)
+ snd_hda_codec_write(codec, port, 0,
+ AC_VERB_SET_EAPD_BTLENABLE,
+ 2);
+ }
+ snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
+ snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
+ (tmp == 5 ? 0x3040 : 0x3050));
+ break;
+ }
+}
+
/*
* ALC880 3-stack model
*
@@ -801,7 +903,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = {
static hda_nid_t alc880_6st_dac_nids[4] = {
/* front, rear, clfe, rear_surr */
0x02, 0x03, 0x04, 0x05
-};
+};
static struct hda_input_mux alc880_6stack_capture_source = {
.num_items = 4,
@@ -1409,25 +1511,43 @@ static struct hda_verb alc880_beep_init_verbs[] = {
};
/* toggle speaker-output according to the hp-jack state */
-static void alc880_uniwill_automute(struct hda_codec *codec)
+static void alc880_uniwill_hp_automute(struct hda_codec *codec)
{
unsigned int present;
+ unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
+}
+
+/* auto-toggle front mic */
+static void alc880_uniwill_mic_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
present = snd_hda_codec_read(codec, 0x18, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+ 0x80, bits);
+}
+
+static void alc880_uniwill_automute(struct hda_codec *codec)
+{
+ alc880_uniwill_hp_automute(codec);
+ alc880_uniwill_mic_automute(codec);
}
static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -1436,22 +1556,28 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
/* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 28 bit!
*/
- if ((res >> 28) == ALC880_HP_EVENT ||
- (res >> 28) == ALC880_MIC_EVENT)
- alc880_uniwill_automute(codec);
+ switch (res >> 28) {
+ case ALC880_HP_EVENT:
+ alc880_uniwill_hp_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc880_uniwill_mic_automute(codec);
+ break;
+ }
}
static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
{
unsigned int present;
+ unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-
+ bits = present ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
}
static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -1480,7 +1606,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
*/
if ((res >> 28) == ALC880_HP_EVENT)
alc880_uniwill_p53_hp_automute(codec);
- if ((res >> 28) == ALC880_DCVOL_EVENT)
+ if ((res >> 28) == ALC880_DCVOL_EVENT)
alc880_uniwill_p53_dcvol_automute(codec);
}
@@ -1547,22 +1673,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
};
/* Enable GPIO mask and set output */
-static struct hda_verb alc880_gpio1_init_verbs[] = {
- {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
-
- { }
-};
-
-/* Enable GPIO mask and set output */
-static struct hda_verb alc880_gpio2_init_verbs[] = {
- {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
-
- { }
-};
+#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
+#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
/* Clevo m520g init */
static struct hda_verb alc880_pin_clevo_init_verbs[] = {
@@ -1734,13 +1846,15 @@ static struct hda_verb alc880_lg_init_verbs[] = {
static void alc880_lg_automute(struct hda_codec *codec)
{
unsigned int present;
+ unsigned char bits;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
}
static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1810,13 +1924,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
static void alc880_lg_lw_automute(struct hda_codec *codec)
{
unsigned int present;
+ unsigned char bits;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
}
static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1916,6 +2032,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_open(codec, &spec->multiout);
}
+static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct alc_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+ stream_tag, format, substream);
+}
+
static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
@@ -1984,7 +2111,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = {
/* NID is set in alc_build_pcms */
.ops = {
.open = alc880_dig_playback_pcm_open,
- .close = alc880_dig_playback_pcm_close
+ .close = alc880_dig_playback_pcm_close,
+ .prepare = alc880_dig_playback_pcm_prepare
},
};
@@ -2075,7 +2203,7 @@ static void alc_free(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
unsigned int i;
- if (! spec)
+ if (!spec)
return;
if (spec->kctl_alloc) {
@@ -2477,7 +2605,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
static struct alc_config_preset alc880_presets[] = {
[ALC880_3ST] = {
.mixers = { alc880_three_stack_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_3stack_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
.dac_nids = alc880_dac_nids,
.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
@@ -2487,7 +2616,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_3ST_DIG] = {
.mixers = { alc880_three_stack_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_3stack_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
.dac_nids = alc880_dac_nids,
.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2509,8 +2639,10 @@ static struct alc_config_preset alc880_presets[] = {
.input_mux = &alc880_capture_source,
},
[ALC880_5ST] = {
- .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+ .mixers = { alc880_three_stack_mixer,
+ alc880_five_stack_mixer},
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_5stack_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
.dac_nids = alc880_dac_nids,
.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
@@ -2518,8 +2650,10 @@ static struct alc_config_preset alc880_presets[] = {
.input_mux = &alc880_capture_source,
},
[ALC880_5ST_DIG] = {
- .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+ .mixers = { alc880_three_stack_mixer,
+ alc880_five_stack_mixer },
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_5stack_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
.dac_nids = alc880_dac_nids,
.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2529,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_6ST] = {
.mixers = { alc880_six_stack_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_6stack_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
.dac_nids = alc880_6st_dac_nids,
.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
@@ -2538,7 +2673,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_6ST_DIG] = {
.mixers = { alc880_six_stack_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_6stack_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
.dac_nids = alc880_6st_dac_nids,
.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2548,7 +2684,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_W810] = {
.mixers = { alc880_w810_base_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_w810_init_verbs,
alc880_gpio2_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
.dac_nids = alc880_w810_dac_nids,
@@ -2559,7 +2696,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_Z71V] = {
.mixers = { alc880_z71v_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_z71v_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
.dac_nids = alc880_z71v_dac_nids,
.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2570,7 +2708,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_F1734] = {
.mixers = { alc880_f1734_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_f1734_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
.dac_nids = alc880_f1734_dac_nids,
.hp_nid = 0x02,
@@ -2580,7 +2719,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_ASUS] = {
.mixers = { alc880_asus_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_asus_init_verbs,
alc880_gpio1_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
.dac_nids = alc880_asus_dac_nids,
@@ -2591,7 +2731,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_ASUS_DIG] = {
.mixers = { alc880_asus_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_asus_init_verbs,
alc880_gpio1_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
.dac_nids = alc880_asus_dac_nids,
@@ -2603,7 +2744,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_ASUS_DIG2] = {
.mixers = { alc880_asus_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_asus_init_verbs,
alc880_gpio2_init_verbs }, /* use GPIO2 */
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
.dac_nids = alc880_asus_dac_nids,
@@ -2615,7 +2757,8 @@ static struct alc_config_preset alc880_presets[] = {
},
[ALC880_ASUS_W1V] = {
.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
- .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+ .init_verbs = { alc880_volume_init_verbs,
+ alc880_pin_asus_init_verbs,
alc880_gpio1_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
.dac_nids = alc880_asus_dac_nids,
@@ -2664,7 +2807,7 @@ static struct alc_config_preset alc880_presets[] = {
.init_hook = alc880_uniwill_p53_hp_automute,
},
[ALC880_FUJITSU] = {
- .mixers = { alc880_fujitsu_mixer,
+ .mixers = { alc880_fujitsu_mixer,
alc880_pcbeep_mixer, },
.init_verbs = { alc880_volume_init_verbs,
alc880_uniwill_p53_init_verbs,
@@ -2707,7 +2850,7 @@ 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 = 1,
+ .num_dacs = 1,
.dac_nids = alc880_dac_nids,
.dig_out_nid = ALC880_DIGOUT_NID,
.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
@@ -2749,18 +2892,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = {
};
/* add dynamic controls */
-static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
+static int add_control(struct alc_spec *spec, int type, const char *name,
+ unsigned long val)
{
struct snd_kcontrol_new *knew;
if (spec->num_kctl_used >= spec->num_kctl_alloc) {
int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
- knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
- if (! knew)
+ /* array + terminator */
+ knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
+ if (!knew)
return -ENOMEM;
if (spec->kctl_alloc) {
- memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
+ memcpy(knew, spec->kctl_alloc,
+ sizeof(*knew) * spec->num_kctl_alloc);
kfree(spec->kctl_alloc);
}
spec->kctl_alloc = knew;
@@ -2770,7 +2916,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
knew = &spec->kctl_alloc[spec->num_kctl_used];
*knew = alc880_control_templates[type];
knew->name = kstrdup(name, GFP_KERNEL);
- if (! knew->name)
+ if (!knew->name)
return -ENOMEM;
knew->private_value = val;
spec->num_kctl_used++;
@@ -2790,7 +2936,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
#define ALC880_PIN_CD_NID 0x1c
/* fill in the dac_nids table from the parsed pin configuration */
-static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
+ const struct auto_pin_cfg *cfg)
{
hda_nid_t nid;
int assigned[4];
@@ -2815,8 +2962,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi
continue;
/* search for an empty channel */
for (j = 0; j < cfg->line_outs; j++) {
- if (! assigned[j]) {
- spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
+ if (!assigned[j]) {
+ spec->multiout.dac_nids[i] =
+ alc880_idx_to_dac(j);
assigned[j] = 1;
break;
}
@@ -2831,36 +2979,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
const struct auto_pin_cfg *cfg)
{
char name[32];
- static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+ static const char *chname[4] = {
+ "Front", "Surround", NULL /*CLFE*/, "Side"
+ };
hda_nid_t nid;
int i, err;
for (i = 0; i < cfg->line_outs; i++) {
- if (! spec->multiout.dac_nids[i])
+ if (!spec->multiout.dac_nids[i])
continue;
nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
if (i == 2) {
/* Center/LFE */
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Center Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "LFE Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "Center Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 2,
+ HDA_INPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "LFE Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 2, 2,
+ HDA_INPUT));
+ if (err < 0)
return err;
} else {
sprintf(name, "%s Playback Volume", chname[i]);
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
sprintf(name, "%s Playback Switch", chname[i]);
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 2,
+ HDA_INPUT));
+ if (err < 0)
return err;
}
}
@@ -2875,51 +3041,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
int err;
char name[32];
- if (! pin)
+ if (!pin)
return 0;
if (alc880_is_fixed_pin(pin)) {
nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
/* specify the DAC as the extra output */
- if (! spec->multiout.hp_nid)
+ if (!spec->multiout.hp_nid)
spec->multiout.hp_nid = nid;
else
spec->multiout.extra_out_nid[0] = nid;
/* control HP volume/switch on the output mixer amp */
nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
sprintf(name, "%s Playback Volume", pfx);
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+ if (err < 0)
return err;
sprintf(name, "%s Playback Switch", pfx);
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
+ if (err < 0)
return err;
} else if (alc880_is_multi_pin(pin)) {
/* set manual connection */
/* we have only a switch on HP-out PIN */
sprintf(name, "%s Playback Switch", pfx);
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+ if (err < 0)
return err;
}
return 0;
}
/* create input playback/capture controls for the given pin */
-static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
+static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
+ const char *ctlname,
int idx, hda_nid_t mix_nid)
{
char name[32];
int err;
sprintf(name, "%s Playback Volume", ctlname);
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
+ if (err < 0)
return err;
sprintf(name, "%s Playback Switch", ctlname);
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
+ if (err < 0)
return err;
return 0;
}
@@ -2939,8 +3111,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
idx, 0x0b);
if (err < 0)
return err;
- imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
- imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
+ imux->items[imux->num_items].label =
+ auto_pin_cfg_labels[i];
+ imux->items[imux->num_items].index =
+ alc880_input_pin_idx(cfg->input_pins[i]);
imux->num_items++;
}
}
@@ -2952,8 +3126,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
int dac_idx)
{
/* set as output */
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ pin_type);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_OUT_UNMUTE);
/* need the manual connection? */
if (alc880_is_multi_pin(nid)) {
struct alc_spec *spec = codec->spec;
@@ -2964,14 +3140,24 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
}
}
+static int get_pin_type(int line_out_type)
+{
+ if (line_out_type == AUTO_PIN_HP_OUT)
+ return PIN_HP;
+ else
+ return PIN_OUT;
+}
+
static void alc880_auto_init_multi_out(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
int i;
-
+
+ alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i < spec->autocfg.line_outs; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
- alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
+ alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
}
}
@@ -2996,37 +3182,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i];
if (alc880_is_input_pin(nid)) {
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ i <= AUTO_PIN_FRONT_MIC ?
+ PIN_VREF80 : PIN_IN);
if (nid != ALC880_PIN_CD_NID)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_MUTE);
}
}
}
/* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+/* return 1 if successful, 0 if the proper config is not found,
+ * or a negative error code
+ */
static int alc880_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
int err;
static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
- if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
- alc880_ignore)) < 0)
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ alc880_ignore);
+ if (err < 0)
return err;
- if (! spec->autocfg.line_outs)
+ if (!spec->autocfg.line_outs)
return 0; /* can't find valid BIOS pin config */
- if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
- (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
- (err = alc880_auto_create_extra_out(spec,
- spec->autocfg.speaker_pins[0],
- "Speaker")) < 0 ||
- (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
- "Headphone")) < 0 ||
- (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+ err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc880_auto_create_extra_out(spec,
+ spec->autocfg.speaker_pins[0],
+ "Speaker");
+ if (err < 0)
+ return err;
+ err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+ "Headphone");
+ if (err < 0)
+ return err;
+ err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
return err;
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -3086,7 +3287,7 @@ static int patch_alc880(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 3-stack mode...\n");
@@ -3105,14 +3306,16 @@ static int patch_alc880(struct hda_codec *codec)
spec->stream_digital_playback = &alc880_pcm_digital_playback;
spec->stream_digital_capture = &alc880_pcm_digital_capture;
- if (! spec->adc_nids && spec->input_mux) {
+ if (!spec->adc_nids && spec->input_mux) {
/* check whether NID 0x07 is valid */
unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
- wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+ /* get type */
+ wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
if (wcap != AC_WID_AUD_IN) {
spec->adc_nids = alc880_adc_nids_alt;
spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
- spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
+ spec->mixers[spec->num_mixers] =
+ alc880_capture_alt_mixer;
spec->num_mixers++;
} else {
spec->adc_nids = alc880_adc_nids;
@@ -3254,7 +3457,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = {
HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
{ } /* end */
-};
+};
static struct snd_kcontrol_new alc260_input_mixer[] = {
HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
@@ -3349,6 +3552,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
{ } /* end */
};
+/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
+ * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
+ */
+static struct snd_kcontrol_new alc260_will_mixer[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+ ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
+ ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+ { } /* end */
+};
+
+/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
+ * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
+ */
+static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+ ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
+ HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
+ ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
+ { } /* end */
+};
+
/* capture mixer elements */
static struct snd_kcontrol_new alc260_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
@@ -3434,7 +3673,9 @@ static struct hda_verb alc260_init_verbs[] = {
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* unmute LINE-2 out pin */
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
- /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+ /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+ * Line In 2 = 0x03
+ */
/* mute CD */
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
/* mute Line In */
@@ -3482,7 +3723,9 @@ static struct hda_verb alc260_hp_init_verbs[] = {
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
/* mute pin widget amp left and right (no gain on this amp) */
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
- /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+ /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+ * Line In 2 = 0x03
+ */
/* unmute CD */
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
/* unmute Line In */
@@ -3530,7 +3773,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
/* mute pin widget amp left and right (no gain on this amp) */
{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
- /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+ /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+ * Line In 2 = 0x03
+ */
/* unmute CD */
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
/* unmute Line In */
@@ -3680,7 +3925,9 @@ static struct hda_verb alc260_acer_init_verbs[] = {
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
- /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
+ /* Unmute Line-out pin widget amp left and right
+ * (no equiv mixer ctrl)
+ */
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -3719,6 +3966,55 @@ static struct hda_verb alc260_acer_init_verbs[] = {
{ }
};
+static struct hda_verb alc260_will_verbs[] = {
+ {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+ {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
+ {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
+ {}
+};
+
+static struct hda_verb alc260_replacer_672v_verbs[] = {
+ {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+ {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
+ {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
+
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+
+ {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc260_replacer_672v_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+
+ /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
+ present = snd_hda_codec_read(codec, 0x0f, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ if (present) {
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
+ snd_hda_codec_write(codec, 0x0f, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+ } else {
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
+ snd_hda_codec_write(codec, 0x0f, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+ }
+}
+
+static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc260_replacer_672v_automute(codec);
+}
+
/* Test configuration for debugging, modelled after the ALC880 test
* configuration.
*/
@@ -3946,10 +4242,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
return 0; /* N/A */
snprintf(name, sizeof(name), "%s Playback Volume", pfx);
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
+ if (err < 0)
return err;
snprintf(name, sizeof(name), "%s Playback Switch", pfx);
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
+ if (err < 0)
return err;
return 1;
}
@@ -3985,7 +4283,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
if (err < 0)
return err;
}
- return 0;
+ return 0;
}
/* create playback/capture controls for input pins */
@@ -3999,20 +4297,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
if (cfg->input_pins[i] >= 0x12) {
idx = cfg->input_pins[i] - 0x12;
err = new_analog_input(spec, cfg->input_pins[i],
- auto_pin_cfg_labels[i], idx, 0x07);
+ auto_pin_cfg_labels[i], idx,
+ 0x07);
if (err < 0)
return err;
- imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+ imux->items[imux->num_items].label =
+ auto_pin_cfg_labels[i];
imux->items[imux->num_items].index = idx;
imux->num_items++;
}
- if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
+ if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
idx = cfg->input_pins[i] - 0x09;
err = new_analog_input(spec, cfg->input_pins[i],
- auto_pin_cfg_labels[i], idx, 0x07);
+ auto_pin_cfg_labels[i], idx,
+ 0x07);
if (err < 0)
return err;
- imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+ imux->items[imux->num_items].label =
+ auto_pin_cfg_labels[i];
imux->items[imux->num_items].index = idx;
imux->num_items++;
}
@@ -4025,14 +4327,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
int sel_idx)
{
/* set as output */
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ pin_type);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_OUT_UNMUTE);
/* need the manual connection? */
if (nid >= 0x12) {
int idx = nid - 0x12;
snd_hda_codec_write(codec, idx + 0x0b, 0,
AC_VERB_SET_CONNECT_SEL, sel_idx);
-
}
}
@@ -4041,9 +4344,12 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
hda_nid_t nid;
- nid = spec->autocfg.line_out_pins[0];
- if (nid)
- alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+ alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
+ nid = spec->autocfg.line_out_pins[0];
+ if (nid) {
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
+ alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
+ }
nid = spec->autocfg.speaker_pins[0];
if (nid)
@@ -4051,8 +4357,8 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
nid = spec->autocfg.hp_pins[0];
if (nid)
- alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
-}
+ alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
+}
#define ALC260_PIN_CD_NID 0x16
static void alc260_auto_init_analog_input(struct hda_codec *codec)
@@ -4063,10 +4369,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i];
if (nid >= 0x12) {
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ i <= AUTO_PIN_FRONT_MIC ?
+ PIN_VREF80 : PIN_IN);
if (nid != ALC260_PIN_CD_NID)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_MUTE);
}
}
@@ -4086,8 +4395,8 @@ static struct hda_verb alc260_volume_init_verbs[] = {
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
- * Note: PASD motherboards uses the Line In 2 as the input for front panel
- * mic (mic 2)
+ * Note: PASD motherboards uses the Line In 2 as the input for
+ * front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -4122,14 +4431,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
int err;
static hda_nid_t alc260_ignore[] = { 0x17, 0 };
- if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
- alc260_ignore)) < 0)
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ alc260_ignore);
+ if (err < 0)
return err;
- if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
+ err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
return err;
- if (! spec->kctl_alloc)
+ if (!spec->kctl_alloc)
return 0; /* can't find valid BIOS pin config */
- if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+ err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
return err;
spec->multiout.max_channels = 2;
@@ -4177,6 +4489,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
[ALC260_HP_3013] = "hp-3013",
[ALC260_FUJITSU_S702X] = "fujitsu",
[ALC260_ACER] = "acer",
+ [ALC260_WILL] = "will",
+ [ALC260_REPLACER_672V] = "replacer",
#ifdef CONFIG_SND_DEBUG
[ALC260_TEST] = "test",
#endif
@@ -4200,6 +4514,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
+ SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
+ SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
{}
};
@@ -4270,6 +4586,34 @@ static struct alc_config_preset alc260_presets[] = {
.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
.input_mux = alc260_acer_capture_sources,
},
+ [ALC260_WILL] = {
+ .mixers = { alc260_will_mixer,
+ alc260_capture_mixer },
+ .init_verbs = { alc260_init_verbs, alc260_will_verbs },
+ .num_dacs = ARRAY_SIZE(alc260_dac_nids),
+ .dac_nids = alc260_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+ .adc_nids = alc260_adc_nids,
+ .dig_out_nid = ALC260_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc260_modes),
+ .channel_mode = alc260_modes,
+ .input_mux = &alc260_capture_source,
+ },
+ [ALC260_REPLACER_672V] = {
+ .mixers = { alc260_replacer_672v_mixer,
+ alc260_capture_mixer },
+ .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
+ .num_dacs = ARRAY_SIZE(alc260_dac_nids),
+ .dac_nids = alc260_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+ .adc_nids = alc260_adc_nids,
+ .dig_out_nid = ALC260_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc260_modes),
+ .channel_mode = alc260_modes,
+ .input_mux = &alc260_capture_source,
+ .unsol_event = alc260_replacer_672v_unsol_event,
+ .init_hook = alc260_replacer_672v_automute,
+ },
#ifdef CONFIG_SND_DEBUG
[ALC260_TEST] = {
.mixers = { alc260_test_mixer,
@@ -4313,7 +4657,7 @@ static int patch_alc260(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");
@@ -4382,7 +4726,8 @@ static struct hda_input_mux alc882_capture_source = {
#define alc882_mux_enum_info alc_mux_enum_info
#define alc882_mux_enum_get alc_mux_enum_get
-static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int alc882_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;
@@ -4396,7 +4741,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && ! codec->in_resume)
+ if (*cur_val == idx && !codec->in_resume)
return 0;
for (i = 0; i < imux->num_items; i++) {
unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -4464,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ 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("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+ HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+ { } /* end */
+};
+
static struct snd_kcontrol_new alc882_chmode_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4559,7 +4919,7 @@ static struct hda_verb alc882_eapd_verbs[] = {
/* change to EAPD mode */
{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
- { }
+ { }
};
/* Mac Pro test */
@@ -4624,6 +4984,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
{ }
};
+
static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
{
unsigned int gpiostate, gpiomask, gpiodir;
@@ -4672,8 +5033,8 @@ static struct hda_verb alc882_auto_init_verbs[] = {
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
- * Note: PASD motherboards uses the Line In 2 as the input for front panel
- * mic (mic 2)
+ * Note: PASD motherboards uses the Line In 2 as the input for
+ * front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -4782,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
[ALC882_3ST_DIG] = "3stack-dig",
[ALC882_6ST_DIG] = "6stack-dig",
[ALC882_ARIMA] = "arima",
+ [ALC882_W2JC] = "w2jc",
[ALC885_MACPRO] = "macpro",
[ALC882_AUTO] = "auto",
};
@@ -4792,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
+ SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
{}
};
@@ -4828,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = {
.channel_mode = alc882_sixstack_modes,
.input_mux = &alc882_capture_source,
},
+ [ALC882_W2JC] = {
+ .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
+ .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
+ alc880_gpio1_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+ .dac_nids = alc882_dac_nids,
+ .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+ .channel_mode = alc880_threestack_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc882_capture_source,
+ .dig_out_nid = ALC882_DIGOUT_NID,
+ },
[ALC885_MACPRO] = {
.mixers = { alc882_macpro_mixer },
.init_verbs = { alc882_macpro_init_verbs },
@@ -4851,15 +5226,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
{
/* set as output */
struct alc_spec *spec = codec->spec;
- int idx;
-
+ int idx;
+
if (spec->multiout.dac_nids[dac_idx] == 0x25)
idx = 4;
else
idx = spec->multiout.dac_nids[dac_idx] - 2;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ pin_type);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_OUT_UNMUTE);
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
}
@@ -4869,10 +5246,13 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
+ alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i <= HDA_SIDE; i++) {
- hda_nid_t nid = spec->autocfg.line_out_pins[i];
+ hda_nid_t nid = spec->autocfg.line_out_pins[i];
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
if (nid)
- alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+ alc882_auto_set_output_and_unmute(codec, nid, pin_type,
+ i);
}
}
@@ -4883,7 +5263,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec)
pin = spec->autocfg.hp_pins[0];
if (pin) /* connect to front */
- alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
+ /* use dac 0 */
+ alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
}
#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
@@ -4897,10 +5278,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i];
if (alc882_is_input_pin(nid)) {
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ i <= AUTO_PIN_FRONT_MIC ?
+ PIN_VREF80 : PIN_IN);
if (nid != ALC882_PIN_CD_NID)
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
AMP_OUT_MUTE);
}
}
@@ -4962,7 +5346,7 @@ static int patch_alc882(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");
@@ -4986,14 +5370,16 @@ static int patch_alc882(struct hda_codec *codec)
spec->stream_digital_playback = &alc882_pcm_digital_playback;
spec->stream_digital_capture = &alc882_pcm_digital_capture;
- if (! spec->adc_nids && spec->input_mux) {
+ if (!spec->adc_nids && spec->input_mux) {
/* check whether NID 0x07 is valid */
unsigned int wcap = get_wcaps(codec, 0x07);
- wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+ /* get type */
+ wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
if (wcap != AC_WID_AUD_IN) {
spec->adc_nids = alc882_adc_nids_alt;
spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
- spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
+ spec->mixers[spec->num_mixers] =
+ alc882_capture_alt_mixer;
spec->num_mixers++;
} else {
spec->adc_nids = alc882_adc_nids;
@@ -5033,6 +5419,7 @@ static hda_nid_t alc883_adc_nids[2] = {
/* ADC1-2 */
0x08, 0x09,
};
+
/* input MUX */
/* FIXME: should be a matrix-type input source selection */
@@ -5045,6 +5432,15 @@ static struct hda_input_mux alc883_capture_source = {
{ "CD", 0x4 },
},
};
+
+static struct hda_input_mux alc883_lenovo_101e_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Mic", 0x1 },
+ { "Line", 0x2 },
+ },
+};
+
#define alc883_mux_enum_info alc_mux_enum_info
#define alc883_mux_enum_get alc_mux_enum_get
@@ -5063,7 +5459,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && ! codec->in_resume)
+ if (*cur_val == idx && !codec->in_resume)
return 0;
for (i = 0; i < imux->num_items; i++) {
unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -5073,6 +5469,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
*cur_val = idx;
return 1;
}
+
/*
* 2ch mode
*/
@@ -5325,7 +5722,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = {
.put = alc883_mux_enum_put,
},
{ } /* end */
-};
+};
static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -5350,7 +5747,30 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
.put = alc883_mux_enum_put,
},
{ } /* end */
-};
+};
+
+static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = alc883_mux_enum_info,
+ .get = alc883_mux_enum_get,
+ .put = alc883_mux_enum_put,
+ },
+ { } /* end */
+};
static struct snd_kcontrol_new alc883_chmode_mixer[] = {
{
@@ -5452,10 +5872,17 @@ static struct hda_verb alc883_tagra_verbs[] = {
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
- {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
- {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
- {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+ {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+ {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+
+ { } /* end */
+};
+static struct hda_verb alc883_lenovo_101e_verbs[] = {
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
{ } /* end */
};
@@ -5463,14 +5890,17 @@ static struct hda_verb alc883_tagra_verbs[] = {
static void alc883_tagra_automute(struct hda_codec *codec)
{
unsigned int present;
+ unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ 0x80, bits);
snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
+ 0x80, bits);
+ snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+ present ? 1 : 3);
}
static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -5479,6 +5909,47 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
alc883_tagra_automute(codec);
}
+static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x14, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+ 0x80, bits);
+}
+
+static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x1b, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+ 0x80, bits);
+}
+
+static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc883_lenovo_101e_all_automute(codec);
+ if ((res >> 26) == ALC880_FRONT_EVENT)
+ alc883_lenovo_101e_ispeaker_automute(codec);
+}
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -5493,8 +5964,8 @@ static struct hda_verb alc883_auto_init_verbs[] = {
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
- * Note: PASD motherboards uses the Line In 2 as the input for front panel
- * mic (mic 2)
+ * Note: PASD motherboards uses the Line In 2 as the input for
+ * front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -5530,13 +6001,13 @@ static struct hda_verb alc883_auto_init_verbs[] = {
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
/* Input mixer2 */
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
{ }
@@ -5584,6 +6055,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
[ALC883_ACER] = "acer",
[ALC883_MEDION] = "medion",
[ALC883_LAPTOP_EAPD] = "laptop-eapd",
+ [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
[ALC883_AUTO] = "auto",
};
@@ -5592,6 +6064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
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),
+ SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
@@ -5609,6 +6082,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
+ SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch),
{}
};
@@ -5639,7 +6113,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_6ch_modes,
.need_dac_fix = 1,
.input_mux = &alc883_capture_source,
- },
+ },
[ALC883_3ST_6ch] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
.init_verbs = { alc883_init_verbs },
@@ -5651,7 +6125,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_6ch_modes,
.need_dac_fix = 1,
.input_mux = &alc883_capture_source,
- },
+ },
[ALC883_6ST_DIG] = {
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
.init_verbs = { alc883_init_verbs },
@@ -5749,6 +6223,19 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
},
+ [ALC883_LENOVO_101E_2ch] = {
+ .mixers = { alc883_lenovo_101e_2ch_mixer},
+ .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_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(alc883_3ST_2ch_modes),
+ .channel_mode = alc883_3ST_2ch_modes,
+ .input_mux = &alc883_lenovo_101e_capture_source,
+ .unsol_event = alc883_lenovo_101e_unsol_event,
+ .init_hook = alc883_lenovo_101e_all_automute,
+ },
};
@@ -5761,8 +6248,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
{
/* set as output */
struct alc_spec *spec = codec->spec;
- int idx;
-
+ int idx;
+
if (spec->multiout.dac_nids[dac_idx] == 0x25)
idx = 4;
else
@@ -5781,10 +6268,13 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
+ alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i <= HDA_SIDE; i++) {
- hda_nid_t nid = spec->autocfg.line_out_pins[i];
+ hda_nid_t nid = spec->autocfg.line_out_pins[i];
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
if (nid)
- alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+ alc883_auto_set_output_and_unmute(codec, nid, pin_type,
+ i);
}
}
@@ -5833,8 +6323,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
else if (err > 0)
/* hack - override the init verbs */
spec->init_verbs[0] = alc883_auto_init_verbs;
- spec->mixers[spec->num_mixers] = alc883_capture_mixer;
- spec->num_mixers++;
+ spec->mixers[spec->num_mixers] = alc883_capture_mixer;
+ spec->num_mixers++;
return err;
}
@@ -5872,7 +6362,7 @@ static int patch_alc883(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");
@@ -5891,7 +6381,7 @@ static int patch_alc883(struct hda_codec *codec)
spec->stream_digital_playback = &alc883_pcm_digital_playback;
spec->stream_digital_capture = &alc883_pcm_digital_capture;
- if (! spec->adc_nids && spec->input_mux) {
+ if (!spec->adc_nids && spec->input_mux) {
spec->adc_nids = alc883_adc_nids;
spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
}
@@ -6028,8 +6518,8 @@ static struct hda_verb alc262_init_verbs[] = {
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
- * Note: PASD motherboards uses the Line In 2 as the input for front panel
- * mic (mic 2)
+ * Note: PASD motherboards uses the Line In 2 as the input for
+ * front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6086,7 +6576,7 @@ static struct hda_verb alc262_init_verbs[] = {
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
{ }
};
@@ -6113,7 +6603,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force)
struct alc_spec *spec = codec->spec;
unsigned int mute;
- if (force || ! spec->sense_updated) {
+ if (force || !spec->sense_updated) {
unsigned int present;
/* need to execute and sync at first */
snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6153,7 +6643,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force)
struct alc_spec *spec = codec->spec;
unsigned int mute;
- if (force || ! spec->sense_updated) {
+ if (force || !spec->sense_updated) {
unsigned int present;
/* need to execute and sync at first */
snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6226,7 +6716,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
struct alc_spec *spec = codec->spec;
unsigned int mute;
- if (force || ! spec->sense_updated) {
+ if (force || !spec->sense_updated) {
unsigned int present;
/* need to execute and sync at first */
snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6331,7 +6821,8 @@ static struct hda_verb alc262_EAPD_verbs[] = {
};
/* 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)
+static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
+ const struct auto_pin_cfg *cfg)
{
hda_nid_t nid;
int err;
@@ -6342,26 +6833,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
nid = cfg->line_out_pins[0];
if (nid) {
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
- HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Front Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+ "Front Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+ if (err < 0)
return err;
}
nid = cfg->speaker_pins[0];
if (nid) {
if (nid == 0x16) {
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
- HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Speaker Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+ "Speaker Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
} else {
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+ "Speaker Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
}
}
@@ -6369,23 +6873,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
if (nid) {
/* spec->multiout.hp_nid = 2; */
if (nid == 0x16) {
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
- HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Headphone Playback Volume",
+ HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+ "Headphone Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
} else {
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+ "Headphone Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
}
}
- return 0;
+ return 0;
}
/* identical with ALC880 */
-#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
+#define alc262_auto_create_analog_input_ctls \
+ alc880_auto_create_analog_input_ctls
/*
* generic initialization of ADC, input mixers and output mixers
@@ -6403,8 +6917,8 @@ static struct hda_verb alc262_volume_init_verbs[] = {
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
- * Note: PASD motherboards uses the Line In 2 as the input for front panel
- * mic (mic 2)
+ * Note: PASD motherboards uses the Line In 2 as the input for
+ * front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6464,8 +6978,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
- * Note: PASD motherboards uses the Line In 2 as the input for front panel
- * mic (mic 2)
+ * Note: PASD motherboards uses the Line In 2 as the input for
+ * front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6647,13 +7161,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
int err;
static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
- if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
- alc262_ignore)) < 0)
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ alc262_ignore);
+ if (err < 0)
return err;
- if (! spec->autocfg.line_outs)
+ if (!spec->autocfg.line_outs)
return 0; /* can't find valid BIOS pin config */
- if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
- (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+ err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
return err;
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -6777,7 +7295,7 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_HP_capture_source,
- },
+ },
[ALC262_HP_BPC_D7000_WF] = {
.mixers = { alc262_HP_BPC_WildWest_mixer },
.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
@@ -6787,7 +7305,7 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_HP_capture_source,
- },
+ },
[ALC262_HP_BPC_D7000_WL] = {
.mixers = { alc262_HP_BPC_WildWest_mixer,
alc262_HP_BPC_WildWest_option_mixer },
@@ -6798,7 +7316,7 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_HP_capture_source,
- },
+ },
[ALC262_BENQ_ED8] = {
.mixers = { alc262_base_mixer },
.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
@@ -6808,7 +7326,7 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
- },
+ },
};
static int patch_alc262(struct hda_codec *codec)
@@ -6823,7 +7341,9 @@ static int patch_alc262(struct hda_codec *codec)
codec->spec = spec;
#if 0
- /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */
+ /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
+ * under-run
+ */
{
int tmp;
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
@@ -6849,7 +7369,7 @@ static int patch_alc262(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");
@@ -6868,15 +7388,17 @@ static int patch_alc262(struct hda_codec *codec)
spec->stream_digital_playback = &alc262_pcm_digital_playback;
spec->stream_digital_capture = &alc262_pcm_digital_capture;
- if (! spec->adc_nids && spec->input_mux) {
+ if (!spec->adc_nids && spec->input_mux) {
/* check whether NID 0x07 is valid */
unsigned int wcap = get_wcaps(codec, 0x07);
- wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+ /* get type */
+ wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
if (wcap != AC_WID_AUD_IN) {
spec->adc_nids = alc262_adc_nids_alt;
spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
- spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
+ spec->mixers[spec->num_mixers] =
+ alc262_capture_alt_mixer;
spec->num_mixers++;
} else {
spec->adc_nids = alc262_adc_nids;
@@ -6904,7 +7426,9 @@ static int patch_alc262(struct hda_codec *codec)
static struct hda_verb alc861_threestack_ch2_init[] = {
/* set pin widget 1Ah (line in) for input */
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
+ /* set pin widget 18h (mic1/2) for input, for mic also enable
+ * the vref
+ */
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
@@ -6961,7 +7485,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
static struct hda_verb alc861_asus_ch2_init[] = {
/* set pin widget 1Ah (line in) for input */
{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
- /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
+ /* set pin widget 18h (mic1/2) for input, for mic also enable
+ * the vref
+ */
{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
@@ -7016,7 +7542,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
-
+
/* Capture mixer control */
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7050,7 +7576,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
-
+
/* Capture mixer control */
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7092,7 +7618,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
},
{ } /* end */
-};
+};
static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
/* output mixer control */
@@ -7113,7 +7639,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
-
+
/* Capture mixer control */
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7134,7 +7660,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
.private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
},
{ } /* end */
-};
+};
static struct snd_kcontrol_new alc861_asus_mixer[] = {
/* output mixer control */
@@ -7154,8 +7680,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */
-
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
+
/* Capture mixer control */
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7239,7 +7765,7 @@ static struct hda_verb alc861_base_init_verbs[] = {
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7249,7 +7775,8 @@ static struct hda_verb alc861_base_init_verbs[] = {
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+ /* hp used DAC 3 (Front) */
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
{ }
@@ -7300,7 +7827,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7310,7 +7837,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+ /* hp used DAC 3 (Front) */
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
{ }
};
@@ -7329,7 +7857,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
/* port-E for HP out (front panel) */
- { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80
+ /* this has to be set to VREF80 */
+ { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
/* route front PCM to HP */
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
/* port-F for mic-in (front panel) with vref */
@@ -7360,7 +7889,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7370,7 +7899,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+ /* hp used DAC 3 (Front) */
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
{ }
};
@@ -7379,7 +7909,9 @@ static struct hda_verb alc861_asus_init_verbs[] = {
/*
* Unmute ADC0 and set the default input to mic-in
*/
- /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/
+ /* port-A for surround (rear panel)
+ * according to codec#0 this is the HP jack
+ */
{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
/* route front PCM to HP */
{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -7391,7 +7923,8 @@ static struct hda_verb alc861_asus_init_verbs[] = {
{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
/* port-E for HP out (front panel) */
- { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */
+ /* this has to be set to VREF80 */
+ { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
/* route front PCM to HP */
{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
/* port-F for mic-in (front panel) with vref */
@@ -7421,7 +7954,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7431,7 +7964,8 @@ static struct hda_verb alc861_asus_init_verbs[] = {
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */
+ /* hp used DAC 3 (Front) */
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
{ }
};
@@ -7450,7 +7984,7 @@ static struct hda_verb alc861_auto_init_verbs[] = {
/*
* Unmute ADC0 and set the default input to mic-in
*/
-// {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
/* Unmute DAC0~3 & spdif out*/
@@ -7483,21 +8017,21 @@ static struct hda_verb alc861_auto_init_verbs[] = {
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1
+ {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
{ }
};
static struct hda_verb alc861_toshiba_init_verbs[] = {
{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
-
+
{ }
};
@@ -7521,9 +8055,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec)
static void alc861_toshiba_unsol_event(struct hda_codec *codec,
unsigned int res)
{
- /* Looks like the unsol event is incompatible with the standard
- * definition. 6bit tag is placed at 26 bit!
- */
if ((res >> 26) == ALC880_HP_EVENT)
alc861_toshiba_automute(codec);
}
@@ -7568,7 +8099,8 @@ static struct hda_input_mux alc861_capture_source = {
};
/* fill in the dac_nids table from the parsed pin configuration */
-static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
+ const struct auto_pin_cfg *cfg)
{
int i;
hda_nid_t nid;
@@ -7591,29 +8123,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
const struct auto_pin_cfg *cfg)
{
char name[32];
- static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+ static const char *chname[4] = {
+ "Front", "Surround", NULL /*CLFE*/, "Side"
+ };
hda_nid_t nid;
int i, idx, err;
for (i = 0; i < cfg->line_outs; i++) {
nid = spec->multiout.dac_nids[i];
- if (! nid)
+ if (!nid)
continue;
if (nid == 0x05) {
/* Center/LFE */
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "Center Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "LFE Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
} else {
- for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
+ for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
+ idx++)
if (nid == alc861_dac_nids[idx])
break;
sprintf(name, "%s Playback Switch", chname[idx]);
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
}
}
@@ -7625,13 +8168,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
int err;
hda_nid_t nid;
- if (! pin)
+ if (!pin)
return 0;
if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
nid = 0x03;
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+ "Headphone Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+ if (err < 0)
return err;
spec->multiout.hp_nid = nid;
}
@@ -7639,32 +8184,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
}
/* create playback/capture controls for input pins */
-static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc861_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, err, idx, idx1;
for (i = 0; i < AUTO_PIN_LAST; i++) {
- switch(cfg->input_pins[i]) {
+ switch (cfg->input_pins[i]) {
case 0x0c:
idx1 = 1;
- idx = 2; // Line In
+ idx = 2; /* Line In */
break;
case 0x0f:
idx1 = 2;
- idx = 2; // Line In
+ idx = 2; /* Line In */
break;
case 0x0d:
idx1 = 0;
- idx = 1; // Mic In
+ idx = 1; /* Mic In */
break;
- case 0x10:
+ case 0x10:
idx1 = 3;
- idx = 1; // Mic In
+ idx = 1; /* Mic In */
break;
case 0x11:
idx1 = 4;
- idx = 0; // CD
+ idx = 0; /* CD */
break;
default:
continue;
@@ -7677,7 +8223,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str
imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
imux->items[imux->num_items].index = idx1;
- imux->num_items++;
+ imux->num_items++;
}
return 0;
}
@@ -7702,13 +8248,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = {
{ } /* end */
};
-static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
+static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
+ hda_nid_t nid,
int pin_type, int dac_idx)
{
/* set as output */
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
- snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+ pin_type);
+ snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_OUT_UNMUTE);
}
@@ -7717,10 +8266,13 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
+ alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
for (i = 0; i < spec->autocfg.line_outs; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
if (nid)
- alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
+ alc861_auto_set_output_and_unmute(codec, nid, pin_type,
+ spec->multiout.dac_nids[i]);
}
}
@@ -7731,7 +8283,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec)
pin = spec->autocfg.hp_pins[0];
if (pin) /* connect to front */
- alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
+ alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
+ spec->multiout.dac_nids[0]);
}
static void alc861_auto_init_analog_input(struct hda_codec *codec)
@@ -7741,31 +8294,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec)
for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i];
- if ((nid>=0x0c) && (nid <=0x11)) {
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
- i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+ if (nid >= 0x0c && nid <= 0x11) {
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ i <= AUTO_PIN_FRONT_MIC ?
+ PIN_VREF80 : PIN_IN);
}
}
}
/* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+/* return 1 if successful, 0 if the proper config is not found,
+ * or a negative error code
+ */
static int alc861_parse_auto_config(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
int err;
static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
- if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
- alc861_ignore)) < 0)
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ alc861_ignore);
+ if (err < 0)
return err;
- if (! spec->autocfg.line_outs)
+ if (!spec->autocfg.line_outs)
return 0; /* can't find valid BIOS pin config */
- if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
- (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
- (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 ||
- (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+ err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
+ if (err < 0)
+ return err;
+ err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
return err;
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -7817,12 +8382,14 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
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(0x1043, 0x1393, "ASUS", ALC861_ASUS),
SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
SND_PCI_QUIRK(0x1179, 0xff00, "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, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
+ SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
{}
};
@@ -7892,7 +8459,8 @@ static struct alc_config_preset alc861_presets[] = {
},
[ALC861_TOSHIBA] = {
.mixers = { alc861_toshiba_mixer },
- .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs },
+ .init_verbs = { alc861_base_init_verbs,
+ alc861_toshiba_init_verbs },
.num_dacs = ARRAY_SIZE(alc861_dac_nids),
.dac_nids = alc861_dac_nids,
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
@@ -7944,7 +8512,7 @@ static int patch_alc861(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- codec->spec = spec;
+ codec->spec = spec;
board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
alc861_models,
@@ -7962,7 +8530,7 @@ static int patch_alc861(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");
@@ -8049,7 +8617,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && ! codec->in_resume)
+ if (*cur_val == idx && !codec->in_resume)
return 0;
for (i = 0; i < imux->num_items; i++) {
unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -8193,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
+ HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, 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("Front Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+
+ { } /* end */
+};
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -8214,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)},
/*
* Set up output mixers (0x02 - 0x05)
@@ -8318,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = {
{ }
};
+static struct hda_verb alc861vd_eapd_verbs[] = {
+ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ { }
+};
+
+static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x1b, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+ 0x80, bits);
+}
+
+static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x18, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+ 0x80, bits);
+}
+
+static void alc861vd_lenovo_automute(struct hda_codec *codec)
+{
+ alc861vd_lenovo_hp_automute(codec);
+ alc861vd_lenovo_mic_automute(codec);
+}
+
+static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ switch (res >> 26) {
+ case ALC880_HP_EVENT:
+ alc861vd_lenovo_hp_automute(codec);
+ break;
+ case ALC880_MIC_EVENT:
+ alc861vd_lenovo_mic_automute(codec);
+ break;
+ }
+}
+
/* pcm configuration: identiacal with ALC880 */
#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
@@ -8332,15 +8983,18 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
[ALC861VD_3ST] = "3stack",
[ALC861VD_3ST_DIG] = "3stack-digout",
[ALC861VD_6ST_DIG] = "6stack-digout",
+ [ALC861VD_LENOVO] = "lenovo",
[ALC861VD_AUTO] = "auto",
};
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(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
- SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST),
+ SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
+ SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
{}
};
@@ -8389,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = {
.channel_mode = alc861vd_6stack_modes,
.input_mux = &alc861vd_capture_source,
},
+ [ALC861VD_LENOVO] = {
+ .mixers = { alc861vd_lenovo_mixer },
+ .init_verbs = { alc861vd_volume_init_verbs,
+ alc861vd_3stack_init_verbs,
+ alc861vd_eapd_verbs,
+ alc861vd_lenovo_unsol_verbs },
+ .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
+ .dac_nids = alc660vd_dac_nids,
+ .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,
+ .unsol_event = alc861vd_lenovo_unsol_event,
+ .init_hook = alc861vd_lenovo_automute,
+ },
};
/*
@@ -8409,11 +9079,13 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int i;
+ alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
for (i = 0; i <= HDA_SIDE; i++) {
hda_nid_t nid = spec->autocfg.line_out_pins[i];
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
if (nid)
alc861vd_auto_set_output_and_unmute(codec, nid,
- PIN_OUT, i);
+ pin_type, i);
}
}
@@ -8466,7 +9138,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
int i, err;
for (i = 0; i < cfg->line_outs; i++) {
- if (! spec->multiout.dac_nids[i])
+ if (!spec->multiout.dac_nids[i])
continue;
nid_v = alc861vd_idx_to_mixer_vol(
alc880_dac_to_idx(
@@ -8477,36 +9149,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
if (i == 2) {
/* Center/LFE */
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
- "Center Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid_v, 1,
- 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Center Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
- "LFE Playback Volume",
- HDA_COMPOSE_AMP_VAL(nid_v, 2,
- 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "LFE Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
- "Center Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid_s, 1,
- 2, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "Center Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
+ HDA_INPUT));
+ if (err < 0)
return err;
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
- "LFE Playback Switch",
- HDA_COMPOSE_AMP_VAL(nid_s, 2,
- 2, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "LFE Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
+ HDA_INPUT));
+ if (err < 0)
return err;
} else {
sprintf(name, "%s Playback Volume", chname[i]);
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid_v, 3,
- 0, HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
return err;
sprintf(name, "%s Playback Switch", chname[i]);
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid_v, 3,
- 2, HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
+ HDA_INPUT));
+ if (err < 0)
return err;
}
}
@@ -8523,13 +9201,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
int err;
char name[32];
- if (! pin)
+ if (!pin)
return 0;
if (alc880_is_fixed_pin(pin)) {
nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
/* specify the DAC as the extra output */
- if (! spec->multiout.hp_nid)
+ if (!spec->multiout.hp_nid)
spec->multiout.hp_nid = nid_v;
else
spec->multiout.extra_out_nid[0] = nid_v;
@@ -8540,22 +9218,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
alc880_fixed_pin_idx(pin));
sprintf(name, "%s Playback Volume", pfx);
- if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
- HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
- HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
+ if (err < 0)
return err;
sprintf(name, "%s Playback Switch", pfx);
- if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
- HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
- HDA_INPUT))) < 0)
+ err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
+ if (err < 0)
return err;
} else if (alc880_is_multi_pin(pin)) {
/* set manual connection */
/* we have only a switch on HP-out PIN */
sprintf(name, "%s Playback Switch", pfx);
- if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
- HDA_COMPOSE_AMP_VAL(pin, 3, 0,
- HDA_OUTPUT))) < 0)
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+ if (err < 0)
return err;
}
return 0;
@@ -8572,21 +9250,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
int err;
static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
- if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
- alc861vd_ignore)) < 0)
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ alc861vd_ignore);
+ if (err < 0)
return err;
- if (! spec->autocfg.line_outs)
+ if (!spec->autocfg.line_outs)
return 0; /* can't find valid BIOS pin config */
- if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
- (err = alc861vd_auto_create_multi_out_ctls(spec,
- &spec->autocfg)) < 0 ||
- (err = alc861vd_auto_create_extra_out(spec,
- spec->autocfg.speaker_pins[0], "Speaker")) < 0 ||
- (err = alc861vd_auto_create_extra_out(spec,
- spec->autocfg.hp_pins[0], "Headphone")) < 0 ||
- (err = alc880_auto_create_analog_input_ctls(spec,
- &spec->autocfg)) < 0)
+ err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc861vd_auto_create_extra_out(spec,
+ spec->autocfg.speaker_pins[0],
+ "Speaker");
+ if (err < 0)
+ return err;
+ err = alc861vd_auto_create_extra_out(spec,
+ spec->autocfg.hp_pins[0],
+ "Headphone");
+ if (err < 0)
+ return err;
+ err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
return err;
spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -8641,7 +9329,7 @@ static int patch_alc861vd(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");
@@ -8675,16 +9363,875 @@ static int patch_alc861vd(struct hda_codec *codec)
}
/*
+ * ALC662 support
+ *
+ * ALC662 is almost identical with ALC880 but has cleaner and more flexible
+ * configuration. Each pin widget can choose any input DACs and a mixer.
+ * Each ADC is connected from a mixer of all inputs. This makes possible
+ * 6-channel independent captures.
+ *
+ * In addition, an independent DAC for the multi-playback (not used in this
+ * driver yet).
+ */
+#define ALC662_DIGOUT_NID 0x06
+#define ALC662_DIGIN_NID 0x0a
+
+static hda_nid_t alc662_dac_nids[4] = {
+ /* front, rear, clfe, rear_surr */
+ 0x02, 0x03, 0x04
+};
+
+static hda_nid_t alc662_adc_nids[1] = {
+ /* ADC1-2 */
+ 0x09,
+};
+/* input MUX */
+/* FIXME: should be a matrix-type input source selection */
+
+static struct hda_input_mux alc662_capture_source = {
+ .num_items = 4,
+ .items = {
+ { "Mic", 0x0 },
+ { "Front Mic", 0x1 },
+ { "Line", 0x2 },
+ { "CD", 0x4 },
+ },
+};
+
+static struct hda_input_mux alc662_lenovo_101e_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Mic", 0x1 },
+ { "Line", 0x2 },
+ },
+};
+#define alc662_mux_enum_info alc_mux_enum_info
+#define alc662_mux_enum_get alc_mux_enum_get
+
+static int alc662_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] = { 0x24, 0x23, 0x22 };
+ 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));
+ }
+ *cur_val = idx;
+ return 1;
+}
+/*
+ * 2ch mode
+ */
+static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
+ { 2, NULL }
+};
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc662_3ST_ch2_init[] = {
+ { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+ { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+ { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+ { } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc662_3ST_ch6_init[] = {
+ { 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, 0x02 },
+ { 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, 0x01 },
+ { } /* end */
+};
+
+static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
+ { 2, alc662_3ST_ch2_init },
+ { 6, alc662_3ST_ch6_init },
+};
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc662_sixstack_ch6_init[] = {
+ { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+ { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+ { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc662_sixstack_ch8_init[] = {
+ { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { } /* end */
+};
+
+static struct hda_channel_mode alc662_5stack_modes[2] = {
+ { 2, alc662_sixstack_ch6_init },
+ { 6, alc662_sixstack_ch8_init },
+};
+
+/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
+ * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
+ */
+
+static struct snd_kcontrol_new alc662_base_mixer[] = {
+ /* output mixer control */
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+ /*Input mixer control */
+ HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
+
+ /* Capture mixer control */
+ HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .count = 1,
+ .info = alc_mux_enum_info,
+ .get = alc_mux_enum_get,
+ .put = alc_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x02, 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_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, 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", 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = alc662_mux_enum_info,
+ .get = alc662_mux_enum_get,
+ .put = alc662_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
+ HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 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_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, 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", 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = alc662_mux_enum_info,
+ .get = alc662_mux_enum_get,
+ .put = alc662_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+ 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, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 1,
+ .info = alc662_mux_enum_info,
+ .get = alc662_mux_enum_get,
+ .put = alc662_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc662_chmode_mixer[] = {
+ {
+ .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 alc662_init_verbs[] = {
+ /* ADC: mute amp left and right */
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* Front mixer: unmute input/output amp left and right (volume = 0) */
+
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+ {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)},
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+ /* Front Pin: output 0 (0x0c) */
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+ /* Rear Pin: output 1 (0x0d) */
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+ /* CLFE Pin: output 2 (0x0e) */
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+ /* Mic (rear) pin: input vref at 80% */
+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Front Mic pin: input vref at 80% */
+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Line In pin: input */
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Line-2 In: Headphone output (output 0 - 0x0c) */
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* CD pin widget for input */
+ {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+
+ /* FIXME: use matrix-type input source selection */
+ /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+ /* Input mixer */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ { }
+};
+
+static struct hda_verb alc662_sue_init_verbs[] = {
+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
+ {}
+};
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc662_auto_init_verbs[] = {
+ /*
+ * Unmute ADC and set the default input to mic-in
+ */
+ {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+ /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ * mixer widget
+ * Note: PASD motherboards uses the Line In 2 as the input for front
+ * panel mic (mic 2)
+ */
+ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+ /*
+ * Set up output mixers (0x0c - 0x0f)
+ */
+ /* set vol=0 to output mixers */
+ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+
+ /* set up input amps for analog loopback */
+ /* Amp Indices: DAC = 0, mixer = 1 */
+ {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)},
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+
+ /* FIXME: use matrix-type input source selection */
+ /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+ /* Input mixer */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+ { }
+};
+
+/* capture mixer elements */
+static struct snd_kcontrol_new alc662_capture_mixer[] = {
+ HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+ {
+ .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 = alc882_mux_enum_info,
+ .get = alc882_mux_enum_get,
+ .put = alc882_mux_enum_put,
+ },
+ { } /* end */
+};
+
+static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x14, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+ 0x80, bits);
+}
+
+static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x1b, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+ 0x80, bits);
+ snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+ 0x80, bits);
+}
+
+static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc662_lenovo_101e_all_automute(codec);
+ if ((res >> 26) == ALC880_FRONT_EVENT)
+ alc662_lenovo_101e_ispeaker_automute(codec);
+}
+
+
+/* pcm configuration: identiacal with ALC880 */
+#define alc662_pcm_analog_playback alc880_pcm_analog_playback
+#define alc662_pcm_analog_capture alc880_pcm_analog_capture
+#define alc662_pcm_digital_playback alc880_pcm_digital_playback
+#define alc662_pcm_digital_capture alc880_pcm_digital_capture
+
+/*
+ * configuration and preset
+ */
+static const char *alc662_models[ALC662_MODEL_LAST] = {
+ [ALC662_3ST_2ch_DIG] = "3stack-dig",
+ [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
+ [ALC662_3ST_6ch] = "3stack-6ch",
+ [ALC662_5ST_DIG] = "6stack-dig",
+ [ALC662_LENOVO_101E] = "lenovo-101e",
+ [ALC662_AUTO] = "auto",
+};
+
+static struct snd_pci_quirk alc662_cfg_tbl[] = {
+ SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
+ {}
+};
+
+static struct alc_config_preset alc662_presets[] = {
+ [ALC662_3ST_2ch_DIG] = {
+ .mixers = { alc662_3ST_2ch_mixer },
+ .init_verbs = { alc662_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+ .adc_nids = alc662_adc_nids,
+ .dig_in_nid = ALC662_DIGIN_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_capture_source,
+ },
+ [ALC662_3ST_6ch_DIG] = {
+ .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+ .init_verbs = { alc662_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+ .adc_nids = alc662_adc_nids,
+ .dig_in_nid = ALC662_DIGIN_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+ .channel_mode = alc662_3ST_6ch_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc662_capture_source,
+ },
+ [ALC662_3ST_6ch] = {
+ .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+ .init_verbs = { alc662_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+ .adc_nids = alc662_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+ .channel_mode = alc662_3ST_6ch_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc662_capture_source,
+ },
+ [ALC662_5ST_DIG] = {
+ .mixers = { alc662_base_mixer, alc662_chmode_mixer },
+ .init_verbs = { alc662_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .dig_out_nid = ALC662_DIGOUT_NID,
+ .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+ .adc_nids = alc662_adc_nids,
+ .dig_in_nid = ALC662_DIGIN_NID,
+ .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
+ .channel_mode = alc662_5stack_modes,
+ .input_mux = &alc662_capture_source,
+ },
+ [ALC662_LENOVO_101E] = {
+ .mixers = { alc662_lenovo_101e_mixer },
+ .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+ .adc_nids = alc662_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_lenovo_101e_capture_source,
+ .unsol_event = alc662_lenovo_101e_unsol_event,
+ .init_hook = alc662_lenovo_101e_all_automute,
+ },
+
+};
+
+
+/*
+ * BIOS auto configuration
+ */
+
+/* add playback controls from the parsed DAC table */
+static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
+ const struct auto_pin_cfg *cfg)
+{
+ char name[32];
+ static const char *chname[4] = {
+ "Front", "Surround", NULL /*CLFE*/, "Side"
+ };
+ hda_nid_t nid;
+ int i, err;
+
+ for (i = 0; i < cfg->line_outs; i++) {
+ if (!spec->multiout.dac_nids[i])
+ continue;
+ nid = alc880_idx_to_dac(i);
+ if (i == 2) {
+ /* Center/LFE */
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Center Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "LFE Playback Volume",
+ HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "Center Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 1, 2,
+ HDA_INPUT));
+ if (err < 0)
+ return err;
+ err = add_control(spec, ALC_CTL_BIND_MUTE,
+ "LFE Playback Switch",
+ HDA_COMPOSE_AMP_VAL(nid, 2, 2,
+ HDA_INPUT));
+ if (err < 0)
+ return err;
+ } else {
+ sprintf(name, "%s Playback Volume", chname[i]);
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+ HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ sprintf(name, "%s Playback Switch", chname[i]);
+ err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 2,
+ HDA_INPUT));
+ if (err < 0)
+ return err;
+ }
+ }
+ return 0;
+}
+
+/* add playback controls for speaker and HP outputs */
+static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+ const char *pfx)
+{
+ hda_nid_t nid;
+ int err;
+ char name[32];
+
+ if (!pin)
+ return 0;
+
+ if (alc880_is_fixed_pin(pin)) {
+ nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
+ /* printk("DAC nid=%x\n",nid); */
+ /* specify the DAC as the extra output */
+ if (!spec->multiout.hp_nid)
+ spec->multiout.hp_nid = nid;
+ else
+ spec->multiout.extra_out_nid[0] = nid;
+ /* control HP volume/switch on the output mixer amp */
+ nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
+ sprintf(name, "%s Playback Volume", pfx);
+ err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ sprintf(name, "%s Playback Switch", pfx);
+ err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
+ if (err < 0)
+ return err;
+ } else if (alc880_is_multi_pin(pin)) {
+ /* set manual connection */
+ /* we have only a switch on HP-out PIN */
+ sprintf(name, "%s Playback Switch", pfx);
+ err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+ HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int alc662_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, err, idx;
+
+ for (i = 0; i < AUTO_PIN_LAST; i++) {
+ if (alc880_is_input_pin(cfg->input_pins[i])) {
+ idx = alc880_input_pin_idx(cfg->input_pins[i]);
+ err = new_analog_input(spec, cfg->input_pins[i],
+ auto_pin_cfg_labels[i],
+ idx, 0x0b);
+ if (err < 0)
+ return err;
+ imux->items[imux->num_items].label =
+ auto_pin_cfg_labels[i];
+ imux->items[imux->num_items].index =
+ alc880_input_pin_idx(cfg->input_pins[i]);
+ imux->num_items++;
+ }
+ }
+ return 0;
+}
+
+static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
+ hda_nid_t nid, int pin_type,
+ int dac_idx)
+{
+ /* set as output */
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+ /* need the manual connection? */
+ if (alc880_is_multi_pin(nid)) {
+ struct alc_spec *spec = codec->spec;
+ int idx = alc880_multi_pin_idx(nid);
+ snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
+ AC_VERB_SET_CONNECT_SEL,
+ alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
+ }
+}
+
+static void alc662_auto_init_multi_out(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ int i;
+
+ for (i = 0; i <= HDA_SIDE; i++) {
+ hda_nid_t nid = spec->autocfg.line_out_pins[i];
+ int pin_type = get_pin_type(spec->autocfg.line_out_type);
+ if (nid)
+ alc662_auto_set_output_and_unmute(codec, nid, pin_type,
+ i);
+ }
+}
+
+static void alc662_auto_init_hp_out(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ hda_nid_t pin;
+
+ pin = spec->autocfg.hp_pins[0];
+ if (pin) /* connect to front */
+ /* use dac 0 */
+ alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
+}
+
+#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
+#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
+
+static void alc662_auto_init_analog_input(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ int i;
+
+ for (i = 0; i < AUTO_PIN_LAST; i++) {
+ hda_nid_t nid = spec->autocfg.input_pins[i];
+ if (alc662_is_input_pin(nid)) {
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ (i <= AUTO_PIN_FRONT_MIC ?
+ PIN_VREF80 : PIN_IN));
+ if (nid != ALC662_PIN_CD_NID)
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_OUT_MUTE);
+ }
+ }
+}
+
+static int alc662_parse_auto_config(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ int err;
+ static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
+
+ err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+ alc662_ignore);
+ if (err < 0)
+ return err;
+ if (!spec->autocfg.line_outs)
+ return 0; /* can't find valid BIOS pin config */
+
+ err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+ err = alc662_auto_create_extra_out(spec,
+ spec->autocfg.speaker_pins[0],
+ "Speaker");
+ if (err < 0)
+ return err;
+ err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+ "Headphone");
+ if (err < 0)
+ return err;
+ err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
+ if (err < 0)
+ return err;
+
+ spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+ if (spec->autocfg.dig_out_pin)
+ spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
+
+ if (spec->kctl_alloc)
+ spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+ spec->num_mux_defs = 1;
+ spec->input_mux = &spec->private_imux;
+
+ 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 err;
+}
+
+/* additional initialization for auto-configuration model */
+static void alc662_auto_init(struct hda_codec *codec)
+{
+ alc662_auto_init_multi_out(codec);
+ alc662_auto_init_hp_out(codec);
+ alc662_auto_init_analog_input(codec);
+}
+
+static int patch_alc662(struct hda_codec *codec)
+{
+ struct alc_spec *spec;
+ int err, board_config;
+
+ spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+ if (!spec)
+ return -ENOMEM;
+
+ codec->spec = spec;
+
+ board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
+ alc662_models,
+ alc662_cfg_tbl);
+ if (board_config < 0) {
+ printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
+ "trying auto-probe from BIOS...\n");
+ board_config = ALC662_AUTO;
+ }
+
+ if (board_config == ALC662_AUTO) {
+ /* automatic parse from the BIOS config */
+ err = alc662_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 = ALC662_3ST_2ch_DIG;
+ }
+ }
+
+ if (board_config != ALC662_AUTO)
+ setup_preset(spec, &alc662_presets[board_config]);
+
+ spec->stream_name_analog = "ALC662 Analog";
+ spec->stream_analog_playback = &alc662_pcm_analog_playback;
+ spec->stream_analog_capture = &alc662_pcm_analog_capture;
+
+ spec->stream_name_digital = "ALC662 Digital";
+ spec->stream_digital_playback = &alc662_pcm_digital_playback;
+ spec->stream_digital_capture = &alc662_pcm_digital_capture;
+
+ if (!spec->adc_nids && spec->input_mux) {
+ spec->adc_nids = alc662_adc_nids;
+ spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
+ }
+
+ codec->patch_ops = alc_patch_ops;
+ if (board_config == ALC662_AUTO)
+ spec->init_hook = alc662_auto_init;
+
+ return 0;
+}
+
+/*
* patch entries
*/
struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
- .patch = patch_alc861 },
+ .patch = patch_alc861 },
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
+ { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
+ .patch = patch_alc883 },
+ { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
+ .patch = patch_alc662 },
{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c94291bc536..93ae9c25076 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -62,6 +62,7 @@ enum {
STAC_MACBOOK,
STAC_MACBOOK_PRO_V1,
STAC_MACBOOK_PRO_V2,
+ STAC_IMAC_INTEL,
STAC_922X_MODELS
};
@@ -175,8 +176,8 @@ static hda_nid_t stac9205_mux_nids[2] = {
0x19, 0x1a
};
-static hda_nid_t stac9205_dmic_nids[3] = {
- 0x17, 0x18, 0
+static hda_nid_t stac9205_dmic_nids[2] = {
+ 0x17, 0x18,
};
static hda_nid_t stac9200_pin_nids[8] = {
@@ -524,12 +525,6 @@ static unsigned int d945gtp5_pin_configs[10] = {
0x02a19320, 0x40000100,
};
-static unsigned int macbook_pin_configs[10] = {
- 0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110,
- 0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e,
- 0x400000fc, 0x400000fb,
-};
-
static unsigned int macbook_pro_v1_pin_configs[10] = {
0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010,
0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e,
@@ -542,14 +537,21 @@ static unsigned int macbook_pro_v2_pin_configs[10] = {
0x400000fc, 0x400000fb,
};
+static unsigned int imac_intel_pin_configs[10] = {
+ 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe,
+ 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa,
+ 0x400000fc, 0x400000fb,
+};
+
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_MACMINI] = d945gtp5_pin_configs,
- [STAC_MACBOOK] = macbook_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] = {
@@ -560,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
[STAC_MACBOOK] = "macbook",
[STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
[STAC_MACBOOK_PRO_V2] = "macbook-pro",
+ [STAC_IMAC_INTEL] = "imac-intel",
};
static struct snd_pci_quirk stac922x_cfg_tbl[] = {
@@ -820,6 +823,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct sigmatel_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+ stream_tag, format, substream);
+}
+
/*
* Analog capture callbacks
@@ -854,7 +868,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
/* NID is set in stac92xx_build_pcms */
.ops = {
.open = stac92xx_dig_playback_pcm_open,
- .close = stac92xx_dig_playback_pcm_close
+ .close = stac92xx_dig_playback_pcm_close,
+ .prepare = stac92xx_dig_playback_pcm_prepare
},
};
@@ -1055,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
{
struct sigmatel_spec *spec = codec->spec;
+ unsigned int wcaps, wtype;
+ int i, num_dacs = 0;
+
+ /* use the wcaps cache to count all DACs available for line-outs */
+ for (i = 0; i < codec->num_nodes; i++) {
+ wcaps = codec->wcaps[i];
+ wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+ if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
+ num_dacs++;
+ }
+ snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
+
switch (cfg->line_outs) {
case 3:
/* add line-in as side */
- if (cfg->input_pins[AUTO_PIN_LINE]) {
+ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
spec->line_switch = 1;
cfg->line_outs++;
@@ -1067,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
break;
case 2:
/* add line-in as clfe and mic as side */
- if (cfg->input_pins[AUTO_PIN_LINE]) {
+ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
spec->line_switch = 1;
cfg->line_outs++;
}
- if (cfg->input_pins[AUTO_PIN_MIC]) {
+ if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
spec->mic_switch = 1;
cfg->line_outs++;
@@ -1080,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
break;
case 1:
/* add line-in as surr and mic as clfe */
- if (cfg->input_pins[AUTO_PIN_LINE]) {
+ if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
spec->line_switch = 1;
cfg->line_outs++;
}
- if (cfg->input_pins[AUTO_PIN_MIC]) {
+ if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
spec->mic_switch = 1;
cfg->line_outs++;
@@ -1096,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
return 0;
}
+
+static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
+{
+ int i;
+
+ for (i = 0; i < spec->multiout.num_dacs; i++) {
+ if (spec->multiout.dac_nids[i] == nid)
+ return 1;
+ }
+
+ return 0;
+}
+
/*
- * XXX The line_out pin widget connection list may not be set to the
- * desired DAC nid. This is the case on 927x where ports A and B can
- * be routed to several DACs.
- *
- * This requires an analysis of the line-out/hp pin configuration
- * to provide a best fit for pin/DAC configurations that are routable.
- * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
- * A and B is not supported.
+ * Fill in the dac_nids table from the parsed pin configuration
+ * This function only works when every pin in line_out_pins[]
+ * contains atleast one DAC in its connection list. Some 92xx
+ * codecs are not connected directly to a DAC, such as the 9200
+ * and 9202/925x. For those, dac_nids[] must be hard-coded.
*/
-/* fill in the dac_nids table from the parsed pin configuration */
static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
struct sigmatel_spec *spec = codec->spec;
- hda_nid_t nid;
- int i;
-
- /* check the pins hardwired to audio widget */
+ int i, j, conn_len = 0;
+ hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
+ unsigned int wcaps, wtype;
+
for (i = 0; i < cfg->line_outs; i++) {
nid = cfg->line_out_pins[i];
- spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
- }
+ conn_len = snd_hda_get_connections(codec, nid, conn,
+ HDA_MAX_CONNECTIONS);
+ for (j = 0; j < conn_len; j++) {
+ wcaps = snd_hda_param_read(codec, conn[j],
+ AC_PAR_AUDIO_WIDGET_CAP);
+ wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+
+ if (wtype != AC_WID_AUD_OUT ||
+ (wcaps & AC_WCAP_DIGITAL))
+ continue;
+ /* conn[j] is a DAC routed to this line-out */
+ if (!is_in_dac_nids(spec, conn[j]))
+ break;
+ }
+
+ if (j == conn_len) {
+ /* error out, no available DAC found */
+ snd_printk(KERN_ERR
+ "%s: No available DAC for pin 0x%x\n",
+ __func__, nid);
+ return -ENODEV;
+ }
- spec->multiout.num_dacs = cfg->line_outs;
+ spec->multiout.dac_nids[i] = conn[j];
+ spec->multiout.num_dacs++;
+ if (conn_len > 1) {
+ /* select this DAC in the pin's input mux */
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CONNECT_SEL, j);
+
+ }
+ }
+ snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
+ spec->multiout.num_dacs,
+ spec->multiout.dac_nids[0],
+ spec->multiout.dac_nids[1],
+ spec->multiout.dac_nids[2],
+ spec->multiout.dac_nids[3],
+ spec->multiout.dac_nids[4]);
return 0;
}
@@ -1189,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
{
- int i;
-
- for (i = 0; i < spec->multiout.num_dacs; i++) {
- if (spec->multiout.dac_nids[i] == nid)
- return 1;
- }
+ if (is_in_dac_nids(spec, nid))
+ return 1;
if (spec->multiout.hp_nid == nid)
return 1;
return 0;
@@ -1236,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
add_spec_dacs(spec, nid);
}
for (i = 0; i < cfg->speaker_outs; i++) {
- nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0,
+ nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
if (check_in_dac_nids(spec, nid))
nid = 0;
- if (check_in_dac_nids(spec, nid))
- nid = 0;
if (! nid)
continue;
add_spec_dacs(spec, nid);
@@ -1355,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
imux->num_items++;
}
- if (imux->num_items == 1) {
+ if (imux->num_items) {
/*
* Set the current input for the muxes.
* The STAC9221 has two input muxes with identical source
@@ -1675,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
{
unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
- if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN))
- return;
+
+ /* if setting pin direction bits, clear the current
+ direction bits first */
+ if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
+ pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
+
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pin_ctl | flag);
@@ -1751,6 +1819,7 @@ static int stac92xx_resume(struct hda_codec *codec)
stac92xx_init(codec);
stac92xx_set_config_regs(codec);
+ snd_hda_resume_ctls(codec, spec->mixer);
for (i = 0; i < spec->num_mixers; i++)
snd_hda_resume_ctls(codec, spec->mixers[i]);
if (spec->multiout.dig_out_nid)
@@ -1905,12 +1974,18 @@ static int patch_stac922x(struct hda_codec *codec)
*/
printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
switch (codec->subsystem_id) {
+ case 0x106b0a00: /* MacBook First generatoin */
+ spec->board_config = STAC_MACBOOK;
+ break;
case 0x106b0200: /* MacBook Pro first generation */
spec->board_config = STAC_MACBOOK_PRO_V1;
break;
case 0x106b1e00: /* MacBook Pro second generation */
spec->board_config = STAC_MACBOOK_PRO_V2;
break;
+ case 0x106b0700: /* Intel-based iMac */
+ spec->board_config = STAC_IMAC_INTEL;
+ break;
}
}
@@ -1931,7 +2006,7 @@ static int patch_stac922x(struct hda_codec *codec)
spec->adc_nids = stac922x_adc_nids;
spec->mux_nids = stac922x_mux_nids;
- spec->num_muxes = 2;
+ spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
spec->num_dmics = 0;
spec->init = stac922x_core_init;
@@ -1992,7 +2067,7 @@ static int patch_stac927x(struct hda_codec *codec)
case STAC_D965_3ST:
spec->adc_nids = stac927x_adc_nids;
spec->mux_nids = stac927x_mux_nids;
- spec->num_muxes = 3;
+ spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
spec->num_dmics = 0;
spec->init = d965_core_init;
spec->mixer = stac9227_mixer;
@@ -2000,7 +2075,7 @@ static int patch_stac927x(struct hda_codec *codec)
case STAC_D965_5ST:
spec->adc_nids = stac927x_adc_nids;
spec->mux_nids = stac927x_mux_nids;
- spec->num_muxes = 3;
+ spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
spec->num_dmics = 0;
spec->init = d965_core_init;
spec->mixer = stac9227_mixer;
@@ -2008,7 +2083,7 @@ static int patch_stac927x(struct hda_codec *codec)
default:
spec->adc_nids = stac927x_adc_nids;
spec->mux_nids = stac927x_mux_nids;
- spec->num_muxes = 3;
+ spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
spec->num_dmics = 0;
spec->init = stac927x_core_init;
spec->mixer = stac927x_mixer;
@@ -2067,9 +2142,9 @@ static int patch_stac9205(struct hda_codec *codec)
spec->adc_nids = stac9205_adc_nids;
spec->mux_nids = stac9205_mux_nids;
- spec->num_muxes = 2;
+ spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
spec->dmic_nids = stac9205_dmic_nids;
- spec->num_dmics = 2;
+ spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
spec->dmux_nid = 0x1d;
spec->init = stac9205_core_init;
@@ -2294,6 +2369,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
+ SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
{}
};
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 2b11ac8689b..ba32d1e52cb 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
+static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct via_spec *spec = codec->spec;
+ return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+ stream_tag, format, substream);
+}
+
/*
* Analog capture
*/
@@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
/* NID is set in via_build_pcms */
.ops = {
.open = via_dig_playback_pcm_open,
- .close = via_dig_playback_pcm_close
+ .close = via_dig_playback_pcm_close,
+ .prepare = via_dig_playback_pcm_prepare
},
};
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 6e22d326df3..44bbb630b94 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
/* entry point */
-const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
{
.subvendor = VT1724_SUBDEVICE_AV710,
.name = "Chaintech AV-710",
diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h
index 7b667bad0c6..a0fc89b4812 100644
--- a/sound/pci/ice1712/amp.h
+++ b/sound/pci/ice1712/amp.h
@@ -42,7 +42,7 @@
#define WM_DAC_CTRL 0x02
#define WM_INT_CTRL 0x03
-extern const struct snd_ice1712_card_info snd_vt1724_amp_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_amp_cards[];
#endif /* __SOUND_AMP_H */
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 6941d85dfec..66bacde1ead 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
* mixers
*/
-static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
@@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
}
};
-static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Playback Switch",
@@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
}
};
-static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "AC97 Playback Switch",
@@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
}
};
-static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "AC97 Playback Switch",
@@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
};
-static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
+static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
@@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
* hence the driver needs to sets up it properly.
*/
-static const unsigned char aureon51_eeprom[] __devinitdata = {
+static unsigned char aureon51_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
@@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = {
[ICE_EEP2_GPIO_STATE2] = 0x00,
};
-static const unsigned char aureon71_eeprom[] __devinitdata = {
+static unsigned char aureon71_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
@@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = {
};
#define prodigy71_eeprom aureon71_eeprom
-static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
+static unsigned char prodigy71lt_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
@@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
#define prodigy71xt_eeprom prodigy71lt_eeprom
/* entry point */
-const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
{
.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
.name = "Terratec Aureon 5.1-Sky",
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
index 79e58e88ed4..c253b8e2c78 100644
--- a/sound/pci/ice1712/aureon.h
+++ b/sound/pci/ice1712/aureon.h
@@ -38,7 +38,7 @@
#define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */
#define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/
-extern const struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
/* GPIO bits */
#define AUREON_CS8415_CS (1 << 22)
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 3eeb36c6e98..af659800c9b 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
return 0;
}
-static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
{
.access = (SNDRV_CTL_ELEM_ACCESS_READ),
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -429,7 +429,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __
* initialize the chips on M-Audio cards
*/
-static const struct snd_akm4xxx akm_audiophile __devinitdata = {
+static struct snd_akm4xxx akm_audiophile __devinitdata = {
.type = SND_AK4528,
.num_adcs = 2,
.num_dacs = 2,
@@ -438,7 +438,7 @@ static const struct snd_akm4xxx akm_audiophile __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
.caddr = 2,
.cif = 0,
.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -450,7 +450,7 @@ static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_delta410 __devinitdata = {
+static struct snd_akm4xxx akm_delta410 __devinitdata = {
.type = SND_AK4529,
.num_adcs = 2,
.num_dacs = 8,
@@ -459,7 +459,7 @@ static const struct snd_akm4xxx akm_delta410 __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
.caddr = 0,
.cif = 0,
.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -471,7 +471,7 @@ static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
+static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
.type = SND_AK4524,
.num_adcs = 8,
.num_dacs = 8,
@@ -481,7 +481,7 @@ static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
.caddr = 2,
.cif = 0, /* the default level of the CIF pin from AK4524 */
.data_mask = ICE1712_DELTA_1010LT_DOUT,
@@ -493,7 +493,7 @@ static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_delta44 __devinitdata = {
+static struct snd_akm4xxx akm_delta44 __devinitdata = {
.type = SND_AK4524,
.num_adcs = 4,
.num_dacs = 4,
@@ -503,7 +503,7 @@ static const struct snd_akm4xxx akm_delta44 __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
.caddr = 2,
.cif = 0, /* the default level of the CIF pin from AK4524 */
.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
@@ -515,7 +515,7 @@ static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_vx442 __devinitdata = {
+static struct snd_akm4xxx akm_vx442 __devinitdata = {
.type = SND_AK4524,
.num_adcs = 4,
.num_dacs = 4,
@@ -525,7 +525,7 @@ static const struct snd_akm4xxx akm_vx442 __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
.caddr = 2,
.cif = 0,
.data_mask = ICE1712_VX442_DOUT,
@@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
* additional controls for M-Audio cards
*/
-static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
@@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
/* entry point */
-const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
{
.subvendor = ICE1712_SUBDEVICE_DELTA1010,
.name = "M Audio Delta 1010",
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index e47861ccd6e..2697156607e 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -46,7 +46,7 @@
#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
/* entry point */
-extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
/*
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 9b7ff302c07..b135389fec6 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
/*
*/
-static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
+static struct snd_akm4xxx akm_ews88mt __devinitdata = {
.num_adcs = 8,
.num_dacs = 8,
.type = SND_AK4524,
@@ -342,7 +342,7 @@ static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -354,7 +354,7 @@ static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
+static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
.num_adcs = 2,
.num_dacs = 2,
.type = SND_AK4524,
@@ -363,7 +363,7 @@ static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -375,7 +375,7 @@ static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_6fire __devinitdata = {
+static struct snd_akm4xxx akm_6fire __devinitdata = {
.num_adcs = 6,
.num_dacs = 6,
.type = SND_AK4524,
@@ -384,7 +384,7 @@ static const struct snd_akm4xxx akm_6fire __devinitdata = {
}
};
-static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_6FIRE_SERIAL_DATA,
@@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn
return val != nval;
}
-static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Input Sensitivity Switch",
@@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
return ndata != data;
}
-static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Input Sensitivity Switch",
.info = snd_ice1712_ewx_io_sense_info,
@@ -687,7 +687,7 @@ static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitda
.count = 8,
};
-static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Output Sensitivity Switch",
.info = snd_ice1712_ewx_io_sense_info,
@@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct
.private_value = xshift | (xinvert << 8),\
}
-static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
@@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str
.private_value = xshift | (xinvert << 8),\
}
-static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Analog Input Select",
@@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
/* entry point */
-const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
{
.subvendor = ICE1712_SUBDEVICE_EWX2496,
.name = "TerraTec EWX24/96",
diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h
index df449b4741f..a12a0b05355 100644
--- a/sound/pci/ice1712/ews.h
+++ b/sound/pci/ice1712/ews.h
@@ -40,7 +40,7 @@
#define ICE1712_SUBDEVICE_PHASE88 0x3b155111
/* entry point */
-extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_ews_cards[];
/* TerraTec EWX 24/96 configuration definitions */
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index df97313aaf8..8203562ef7e 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
{
/* Hoontech STDSP24 with modified hardware */
- static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
+ static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
.num_adcs = 2,
.num_dacs = 2,
.type = SND_AK4524,
@@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
}
};
- static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
+ static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_STDSP24_SERIAL_DATA,
@@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
/* entry point */
-const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
{
.subvendor = ICE1712_SUBDEVICE_STDSP24,
.name = "Hoontech SoundTrack Audio DSP24",
diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h
index b62d6e4f6c7..1ee538b20fb 100644
--- a/sound/pci/ice1712/hoontech.h
+++ b/sound/pci/ice1712/hoontech.h
@@ -35,7 +35,7 @@
#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */
-extern const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 830a1bbd711..6630a0ae952 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -287,7 +287,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
return val != nval;
}
-static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Digital Mixer To AC97",
.info = snd_ice1712_digmix_route_ac97_info,
@@ -977,11 +977,9 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream,
{
unsigned int what = 0;
unsigned int old;
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == ice->playback_pro_substream) {
what |= ICE1712_PLAYBACK_START;
snd_pcm_trigger_done(s, substream);
@@ -1380,7 +1378,7 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc
static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0);
-static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Playback Switch",
@@ -1404,7 +1402,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devini
},
};
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "H/W Multi Capture Switch",
.info = snd_ice1712_pro_mixer_switch_info,
@@ -1413,7 +1411,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __d
.private_value = 10,
};
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH),
.info = snd_ice1712_pro_mixer_switch_info,
@@ -1423,7 +1421,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __de
.count = 2,
};
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -1435,7 +1433,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __d
.tlv = { .p = db_scale_playback }
};
-static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME),
.info = snd_ice1712_pro_mixer_volume_info,
@@ -1627,7 +1625,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
.name = "ICE1712 EEPROM",
.access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1663,7 +1661,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1714,7 +1712,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1723,7 +1721,7 @@ static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
.get = snd_ice1712_spdif_maskc_get,
};
-static const struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1750,7 +1748,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
{
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_INACTIVE),
@@ -1891,7 +1889,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Internal Clock",
.info = snd_ice1712_pro_internal_clock_info,
@@ -1962,7 +1960,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont
return change;
}
-static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Internal Clock Default",
.info = snd_ice1712_pro_internal_clock_default_info,
@@ -2001,7 +1999,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Rate Locking",
.info = snd_ice1712_pro_rate_locking_info,
@@ -2040,7 +2038,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Rate Reset",
.info = snd_ice1712_pro_rate_reset_info,
@@ -2207,7 +2205,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "H/W Playback Route",
.info = snd_ice1712_pro_route_info,
@@ -2215,7 +2213,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devini
.put = snd_ice1712_pro_route_analog_put,
};
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
.info = snd_ice1712_pro_route_info,
@@ -2257,7 +2255,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Volume Rate",
.info = snd_ice1712_pro_volume_rate_info,
@@ -2290,7 +2288,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Peak",
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -2305,7 +2303,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata =
/*
* list of available boards
*/
-static const struct snd_ice1712_card_info *card_tables[] __devinitdata = {
+static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
snd_ice1712_hoontech_cards,
snd_ice1712_delta_cards,
snd_ice1712_ews_cards,
@@ -2329,7 +2327,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
{
int dev = 0xa0; /* EEPROM device address */
unsigned int i, size;
- const struct snd_ice1712_card_info **tbl, *c;
+ struct snd_ice1712_card_info * const *tbl, *c;
if (! modelname || ! *modelname) {
ice->eeprom.subvendor = 0;
@@ -2658,7 +2656,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
*
*/
-static const struct snd_ice1712_card_info no_matched __devinitdata;
+static struct snd_ice1712_card_info no_matched __devinitdata;
static int __devinit snd_ice1712_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
@@ -2667,7 +2665,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
struct snd_card *card;
struct snd_ice1712 *ice;
int pcm_dev = 0, err;
- const struct snd_ice1712_card_info **tbl, *c;
+ struct snd_ice1712_card_info * const *tbl, *c;
if (dev >= SNDRV_CARDS)
return -ENODEV;
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index c3d9feaaf57..6ac486d9c13 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -397,6 +397,9 @@ struct snd_ice1712 {
struct ak4114 *ak4114;
unsigned int analog: 1;
} juli;
+ struct {
+ struct ak4114 *ak4114;
+ } prodigy192;
} spec;
};
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 1127ebdf5fe..ee620dea7ef 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -337,13 +337,11 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
unsigned char what;
unsigned char old;
- struct list_head *pos;
struct snd_pcm_substream *s;
what = 0;
- snd_pcm_group_for_each(pos, substream) {
+ snd_pcm_group_for_each_entry(s, substream) {
const struct vt1724_pcm_reg *reg;
- s = snd_pcm_group_substream_entry(pos);
reg = s->runtime->private_data;
what |= reg->start;
snd_pcm_trigger_done(s, substream);
@@ -1318,7 +1316,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_CARD,
.name = "ICE1724 EEPROM",
.access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1431,7 +1429,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
return (val != old);
}
-static const struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1463,7 +1461,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1472,7 +1470,7 @@ static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
.get = snd_vt1724_spdif_maskc_get,
};
-static const struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1517,7 +1515,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
return old != val;
}
-static const struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
/* FIXME: the following conflict with IEC958 Playback Route */
@@ -1668,7 +1666,12 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
spin_lock_irq(&ice->reg_lock);
oval = inb(ICEMT1724(ice, RATE));
if (ucontrol->value.enumerated.item[0] == spdif) {
+ unsigned char i2s_oval;
outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
+ /* setting 256fs */
+ i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT));
+ outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X,
+ ICEMT1724(ice, I2S_FORMAT));
} else {
rate = rates[ucontrol->value.integer.value[0] % 15];
if (rate <= get_max_rate(ice)) {
@@ -1695,7 +1698,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Internal Clock",
.info = snd_vt1724_pro_internal_clock_info,
@@ -1734,7 +1737,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Rate Locking",
.info = snd_vt1724_pro_rate_locking_info,
@@ -1773,7 +1776,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
return change;
}
-static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Rate Reset",
.info = snd_vt1724_pro_rate_reset_info,
@@ -1892,7 +1895,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
digital_route_shift(idx));
}
-static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "H/W Playback Route",
.info = snd_vt1724_pro_route_info,
@@ -1900,7 +1903,7 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinit
.put = snd_vt1724_pro_route_analog_put,
};
-static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
.info = snd_vt1724_pro_route_info,
@@ -1936,7 +1939,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Multi Track Peak",
.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -1948,9 +1951,9 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
*
*/
-static const struct snd_ice1712_card_info no_matched __devinitdata;
+static struct snd_ice1712_card_info no_matched __devinitdata;
-static const struct snd_ice1712_card_info *card_tables[] __devinitdata = {
+static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
snd_vt1724_revo_cards,
snd_vt1724_amp_cards,
snd_vt1724_aureon_cards,
@@ -2009,7 +2012,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
{
const int dev = 0xa0; /* EEPROM device address */
unsigned int i, size;
- const struct snd_ice1712_card_info **tbl, *c;
+ struct snd_ice1712_card_info * const *tbl, *c;
if (! modelname || ! *modelname) {
ice->eeprom.subvendor = 0;
@@ -2308,7 +2311,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
struct snd_card *card;
struct snd_ice1712 *ice;
int pcm_dev = 0, err;
- const struct snd_ice1712_card_info **tbl, *c;
+ struct snd_ice1712_card_info * const *tbl, *c;
if (dev >= SNDRV_CARDS)
return -ENODEV;
@@ -2347,6 +2350,14 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
}
c = &no_matched;
__found:
+ /*
+ * VT1724 has separate DMAs for the analog and the SPDIF streams while
+ * ICE1712 has only one for both (mixed up).
+ *
+ * Confusingly the analog PCM is named "professional" here because it
+ * was called so in ice1712 driver, and vt1724 driver is derived from
+ * ice1712 driver.
+ */
if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) {
snd_card_free(card);
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index d88172fa95d..3d8e74e493d 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -125,7 +125,7 @@ static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
snd_akm4xxx_reset(ak, 0);
}
-static const struct snd_akm4xxx akm_juli_dac __devinitdata = {
+static struct snd_akm4xxx akm_juli_dac __devinitdata = {
.type = SND_AK4358,
.num_dacs = 2,
.ops = {
@@ -138,7 +138,16 @@ static const struct snd_akm4xxx akm_juli_dac __devinitdata = {
static int __devinit juli_add_controls(struct snd_ice1712 *ice)
{
- return snd_ice1712_akm4xxx_build_controls(ice);
+ int err;
+ err = snd_ice1712_akm4xxx_build_controls(ice);
+ if (err < 0)
+ return err;
+ /* only capture SPDIF over AK4114 */
+ err = snd_ak4114_build(ice->spec.juli.ak4114, NULL,
+ ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
+ if (err < 0)
+ return err;
+ return 0;
}
/*
@@ -160,13 +169,6 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
int err;
struct snd_akm4xxx *ak;
-#if 0
- for (err = 0; err < 0x20; err++)
- juli_ak4114_read(ice, err);
- juli_ak4114_write(ice, 0, 0x0f);
- juli_ak4114_read(ice, 0);
- juli_ak4114_read(ice, 1);
-#endif
err = snd_ak4114_create(ice->card,
juli_ak4114_read,
juli_ak4114_write,
@@ -206,7 +208,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
* hence the driver needs to sets up it properly.
*/
-static const unsigned char juli_eeprom[] __devinitdata = {
+static unsigned char juli_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
@@ -223,7 +225,7 @@ static const unsigned char juli_eeprom[] __devinitdata = {
};
/* entry point */
-const struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
{
.subvendor = VT1724_SUBDEVICE_JULI,
.name = "ESI Juli@",
diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h
index 1b9294f8bce..d9f8534fd92 100644
--- a/sound/pci/ice1712/juli.h
+++ b/sound/pci/ice1712/juli.h
@@ -5,6 +5,6 @@
#define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */
-extern const struct snd_ice1712_card_info snd_vt1724_juli_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_juli_cards[];
#endif /* __SOUND_JULI_H */
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 0751718f4d7..40a9098af77 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -89,13 +89,13 @@ static const unsigned char wm_vol[256] = {
#define WM_VOL_MAX (sizeof(wm_vol) - 1)
#define WM_VOL_MUTE 0x8000
-static const struct snd_akm4xxx akm_phase22 __devinitdata = {
+static struct snd_akm4xxx akm_phase22 __devinitdata = {
.type = SND_AK4524,
.num_dacs = 2,
.num_adcs = 2,
};
-static const struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
.caddr = 2,
.cif = 1,
.data_mask = 1 << 4,
@@ -152,7 +152,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
return 0;
}
-static const unsigned char phase22_eeprom[] __devinitdata = {
+static unsigned char phase22_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */
@@ -168,7 +168,7 @@ static const unsigned char phase22_eeprom[] __devinitdata = {
[ICE_EEP2_GPIO_STATE2] = 0x00,
};
-static const unsigned char phase28_eeprom[] __devinitdata = {
+static unsigned char phase28_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
@@ -700,7 +700,7 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct
static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
-static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
@@ -815,7 +815,7 @@ static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
}
};
-static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "PCM Playback Switch",
@@ -870,7 +870,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
return 0;
}
-const struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
{
.subvendor = VT1724_SUBDEVICE_PHASE22,
.name = "Terratec PHASE 22",
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h
index ad379a99bf9..13e841b5548 100644
--- a/sound/pci/ice1712/phase.h
+++ b/sound/pci/ice1712/phase.h
@@ -31,7 +31,7 @@
#define VT1724_SUBDEVICE_PHASE28 0x3b154911
/* entry point */
-extern const struct snd_ice1712_card_info snd_vt1724_phase_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
/* PHASE28 GPIO bits */
#define PHASE28_SPI_MISO (1 << 21)
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 9552497f076..01c69453dde 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -571,7 +571,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);
* mixers
*/
-static const struct snd_kcontrol_new pontis_controls[] __devinitdata = {
+static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -826,7 +826,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
* hence the driver needs to sets up it properly.
*/
-static const unsigned char pontis_eeprom[] __devinitdata = {
+static unsigned char pontis_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
@@ -843,7 +843,7 @@ static const unsigned char pontis_eeprom[] __devinitdata = {
};
/* entry point */
-const struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
{
.subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
.name = "Pontis MS300",
diff --git a/sound/pci/ice1712/pontis.h b/sound/pci/ice1712/pontis.h
index 1a418255c19..d0d1378b935 100644
--- a/sound/pci/ice1712/pontis.h
+++ b/sound/pci/ice1712/pontis.h
@@ -28,6 +28,6 @@
#define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */
-extern const struct snd_ice1712_card_info snd_vt1720_pontis_cards[];
+extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[];
#endif /* __SOUND_PONTIS_H */
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 31cc66eb9f8..f03c02c0774 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -2,6 +2,37 @@
* ALSA driver for ICEnsemble VT1724 (Envy24HT)
*
* Lowlevel functions for AudioTrak Prodigy 192 cards
+ * Supported IEC958 input from optional MI/ODI/O add-on card.
+ *
+ * Specifics (SW, HW):
+ * -------------------
+ * * 49.5MHz crystal
+ * * SPDIF-OUT on the card:
+ * - coax (through isolation transformer)/toslink supplied by
+ * 74HC04 gates - 3 in parallel
+ * - output switched between on-board CD drive dig-out connector
+ * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled
+ * by GPIO20 (0 = CD dig-out, 1 = SPDTX)
+ * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax
+ *
+ * * MI/ODI/O card: AK4114 based, used for iec958 input only
+ * - toslink input -> RX0
+ * - coax input -> RX1
+ * - 4wire protocol:
+ * AK4114 ICE1724
+ * ------------------------------
+ * CDTO (pin 32) -- GPIO11 pin 86
+ * CDTI (pin 33) -- GPIO10 pin 77
+ * CCLK (pin 34) -- GPIO9 pin 76
+ * CSN (pin 35) -- GPIO8 pin 75
+ * - output data Mode 7 (24bit, I2S, slave)
+ * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which
+ * outputs master clock to SPMCLKIN of ice1724.
+ * Experimentally I found out that only a combination of
+ * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 -
+ * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct
+ * sampling rate. That means the the FPGA doubles the
+ * MCK01 rate.
*
* Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
* Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca>
@@ -356,6 +387,47 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
return 0;
}
#endif
+static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[2] = { "Line In", "Mic" };
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+
+ return 0;
+}
+
+
+static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+ unsigned char val;
+
+ val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
+ ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1;
+ return 0;
+}
+
+static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+ unsigned char new, old;
+ int change;
+ old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
+ new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80);
+ change = (new != old);
+ if (change)
+ stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
+ return change;
+}
static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
@@ -364,7 +436,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
* mixers
*/
-static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
+static struct snd_kcontrol_new stac_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
@@ -406,7 +478,7 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "ADC Switch",
+ .name = "ADC Capture Switch",
.count = 1,
.info = stac9460_adc_mute_info,
.get = stac9460_adc_mute_get,
@@ -417,13 +489,21 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
- .name = "ADC Volume",
+ .name = "ADC Capture Volume",
.count = 1,
.info = stac9460_adc_vol_info,
.get = stac9460_adc_vol_get,
.put = stac9460_adc_vol_put,
.tlv = { .p = db_scale_adc }
},
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Analog Capture Input",
+ .info = stac9460_mic_sw_info,
+ .get = stac9460_mic_sw_get,
+ .put = stac9460_mic_sw_put,
+
+ },
#if 0
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -456,19 +536,261 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
#endif
};
+
+/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */
+/* CDTO (pin 32) -- GPIO11 pin 86
+ * CDTI (pin 33) -- GPIO10 pin 77
+ * CCLK (pin 34) -- GPIO9 pin 76
+ * CSN (pin 35) -- GPIO8 pin 75
+ */
+#define AK4114_ADDR 0x00 /* C1-C0: Chip Address
+ * (According to datasheet fixed to “00â€)
+ */
+
+/*
+ * 4wire ak4114 protocol - writing data
+ */
+static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
+ unsigned int data, int idx)
+{
+ for (; idx >= 0; idx--) {
+ /* drop clock */
+ gpio &= ~VT1724_PRODIGY192_CCLK;
+ snd_ice1712_gpio_write(ice, gpio);
+ udelay(1);
+ /* set data */
+ if (data & (1 << idx))
+ gpio |= VT1724_PRODIGY192_CDOUT;
+ else
+ gpio &= ~VT1724_PRODIGY192_CDOUT;
+ snd_ice1712_gpio_write(ice, gpio);
+ udelay(1);
+ /* raise clock */
+ gpio |= VT1724_PRODIGY192_CCLK;
+ snd_ice1712_gpio_write(ice, gpio);
+ udelay(1);
+ }
+}
+
+/*
+ * 4wire ak4114 protocol - reading data
+ */
+static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
+ int idx)
+{
+ unsigned char data = 0;
+
+ for (; idx >= 0; idx--) {
+ /* drop clock */
+ gpio &= ~VT1724_PRODIGY192_CCLK;
+ snd_ice1712_gpio_write(ice, gpio);
+ udelay(1);
+ /* read data */
+ if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN)
+ data |= (1 << idx);
+ udelay(1);
+ /* raise clock */
+ gpio |= VT1724_PRODIGY192_CCLK;
+ snd_ice1712_gpio_write(ice, gpio);
+ udelay(1);
+ }
+ return data;
+}
+/*
+ * 4wire ak4114 protocol - starting sequence
+ */
+static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice)
+{
+ unsigned int tmp;
+
+ snd_ice1712_save_gpio_status(ice);
+ tmp = snd_ice1712_gpio_read(ice);
+
+ tmp |= VT1724_PRODIGY192_CCLK; /* high at init */
+ tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */
+ snd_ice1712_gpio_write(ice, tmp);
+ udelay(1);
+ return tmp;
+}
+
+/*
+ * 4wire ak4114 protocol - final sequence
+ */
+static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
+{
+ tmp |= VT1724_PRODIGY192_CS; /* raise chip select */
+ snd_ice1712_gpio_write(ice, tmp);
+ udelay(1);
+ snd_ice1712_restore_gpio_status(ice);
+}
+
+/*
+ * Write data to addr register of ak4114
+ */
+static void prodigy192_ak4114_write(void *private_data, unsigned char addr,
+ unsigned char data)
+{
+ struct snd_ice1712 *ice = private_data;
+ unsigned int tmp, addrdata;
+ tmp = prodigy192_4wire_start(ice);
+ addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
+ addrdata = (addrdata << 8) | data;
+ write_data(ice, tmp, addrdata, 15);
+ prodigy192_4wire_finish(ice, tmp);
+}
+
+/*
+ * Read data from addr register of ak4114
+ */
+static unsigned char prodigy192_ak4114_read(void *private_data,
+ unsigned char addr)
+{
+ struct snd_ice1712 *ice = private_data;
+ unsigned int tmp;
+ unsigned char data;
+
+ tmp = prodigy192_4wire_start(ice);
+ write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
+ data = read_data(ice, tmp, 7);
+ prodigy192_4wire_finish(ice, tmp);
+ return data;
+}
+
+
+static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ static char *texts[2] = { "Toslink", "Coax" };
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+ uinfo->count = 1;
+ uinfo->value.enumerated.items = 2;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+ strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ return 0;
+}
+
+
+static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+ unsigned char val;
+
+ val = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
+ /* AK4114_IPS0 bit = 0 -> RX0 = Toslink
+ * AK4114_IPS0 bit = 1 -> RX1 = Coax
+ */
+ ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0;
+ return 0;
+}
+
+static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+ unsigned char new, old, itemvalue;
+ int change;
+
+ old = prodigy192_ak4114_read(ice, AK4114_REG_IO1);
+ /* AK4114_IPS0 could be any bit */
+ itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00;
+
+ new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0);
+ change = (new != old);
+ if (change)
+ prodigy192_ak4114_write(ice, AK4114_REG_IO1, new);
+ return change;
+}
+
+
+static const struct snd_kcontrol_new ak4114_controls[] __devinitdata = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "MIODIO IEC958 Capture Input",
+ .info = ak4114_input_sw_info,
+ .get = ak4114_input_sw_get,
+ .put = ak4114_input_sw_put,
+
+ }
+};
+
+
+static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
+{
+ static const unsigned char ak4114_init_vals[] = {
+ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
+ /* ice1724 expects I2S and provides clock,
+ * DEM0 disables the deemphasis filter
+ */
+ AK4114_DIF_I24I2S | AK4114_DEM0 ,
+ AK4114_TX1E,
+ AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */
+ 0,
+ 0
+ };
+ static const unsigned char ak4114_init_txcsb[] = {
+ 0x41, 0x02, 0x2c, 0x00, 0x00
+ };
+
+ return snd_ak4114_create(ice->card,
+ prodigy192_ak4114_read,
+ prodigy192_ak4114_write,
+ ak4114_init_vals, ak4114_init_txcsb,
+ ice, &ice->spec.prodigy192.ak4114);
+}
+
static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
{
unsigned int i;
int err;
for (i = 0; i < ARRAY_SIZE(stac_controls); i++) {
- err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice));
+ err = snd_ctl_add(ice->card,
+ snd_ctl_new1(&stac_controls[i], ice));
+ if (err < 0)
+ return err;
+ }
+ if (ice->spec.prodigy192.ak4114) {
+ /* ak4114 is connected */
+ for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) {
+ err = snd_ctl_add(ice->card,
+ snd_ctl_new1(&ak4114_controls[i],
+ ice));
+ if (err < 0)
+ return err;
+ }
+ err = snd_ak4114_build(ice->spec.prodigy192.ak4114,
+ NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */
+ ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
if (err < 0)
return err;
}
return 0;
}
+/*
+ * check for presence of MI/ODI/O add-on card with digital inputs
+ */
+static int prodigy192_miodio_exists(struct snd_ice1712 *ice)
+{
+
+ unsigned char orig_value;
+ const unsigned char test_data = 0xd1; /* random value */
+ unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */
+ int exists = 0;
+
+ orig_value = prodigy192_ak4114_read(ice, addr);
+ prodigy192_ak4114_write(ice, addr, test_data);
+ if (prodigy192_ak4114_read(ice, addr) == test_data) {
+ /* ak4114 seems to communicate, apparently exists */
+ /* writing back original value */
+ prodigy192_ak4114_write(ice, addr, orig_value);
+ exists = 1;
+ }
+ return exists;
+}
/*
* initialize the chip
@@ -487,16 +809,30 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
(unsigned short)-1
};
const unsigned short *p;
+ int err = 0;
/* prodigy 192 */
ice->num_total_dacs = 6;
ice->num_total_adcs = 2;
+ ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */
/* initialize codec */
p = stac_inits_prodigy;
for (; *p != (unsigned short)-1; p += 2)
stac9460_put(ice, p[0], p[1]);
+ /* MI/ODI/O add on card with AK4114 */
+ if (prodigy192_miodio_exists(ice)) {
+ err = prodigy192_ak4114_init(ice);
+ /* from this moment if err = 0 then
+ * ice->spec.prodigy192.ak4114 should not be null
+ */
+ snd_printdd("AK4114 initialized with status %d\n", err);
+ } else
+ snd_printdd("AK4114 not found\n");
+ if (err < 0)
+ return err;
+
return 0;
}
@@ -506,25 +842,31 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
* hence the driver needs to sets up it properly.
*/
-static const unsigned char prodigy71_eeprom[] __devinitdata = {
- [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */
+static unsigned char prodigy71_eeprom[] __devinitdata = {
+ [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401,
+ * spdif-in+ 1 stereo ADC,
+ * 3 stereo DACs
+ */
[ICE_EEP2_ACLINK] = 0x80, /* I2S */
[ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
[ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
[ICE_EEP2_GPIO_DIR] = 0xff,
- [ICE_EEP2_GPIO_DIR1] = 0xff,
+ [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) ,
[ICE_EEP2_GPIO_DIR2] = 0xbf,
[ICE_EEP2_GPIO_MASK] = 0x00,
[ICE_EEP2_GPIO_MASK1] = 0x00,
[ICE_EEP2_GPIO_MASK2] = 0x00,
[ICE_EEP2_GPIO_STATE] = 0x00,
[ICE_EEP2_GPIO_STATE1] = 0x00,
- [ICE_EEP2_GPIO_STATE2] = 0x00,
+ [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input
+ * passthrough,
+ * 1 = SPDIF-OUT from ice1724
+ */
};
/* entry point */
-const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
{
.subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
.name = "Audiotrak Prodigy 192",
diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h
index 2fa2e62b9e0..16a53b459c7 100644
--- a/sound/pci/ice1712/prodigy192.h
+++ b/sound/pci/ice1712/prodigy192.h
@@ -5,7 +5,15 @@
#define PRODIGY192_STAC9460_ADDR 0x54
#define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */
+/*
+ * AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with
+ * AK4114 (SPDIF-IN)
+ */
+#define VT1724_PRODIGY192_CS (1 << 8) /* GPIO8, pin 75 */
+#define VT1724_PRODIGY192_CCLK (1 << 9) /* GPIO9, pin 76 */
+#define VT1724_PRODIGY192_CDOUT (1 << 10) /* GPIO10, pin 77 */
+#define VT1724_PRODIGY192_CDIN (1 << 11) /* GPIO11, pin 86 */
-extern const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[];
#endif /* __SOUND_PRODIGY192_H */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index 025a7e8497c..690ceb34064 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -219,7 +219,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
},
};
-static const struct snd_akm4xxx akm_revo_front __devinitdata = {
+static struct snd_akm4xxx akm_revo_front __devinitdata = {
.type = SND_AK4381,
.num_dacs = 2,
.ops = {
@@ -228,7 +228,7 @@ static const struct snd_akm4xxx akm_revo_front __devinitdata = {
.dac_info = revo71_front,
};
-static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
.caddr = 1,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -240,7 +240,7 @@ static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_revo_surround __devinitdata = {
+static struct snd_akm4xxx akm_revo_surround __devinitdata = {
.type = SND_AK4355,
.idx_offset = 1,
.num_dacs = 6,
@@ -250,7 +250,7 @@ static const struct snd_akm4xxx akm_revo_surround __devinitdata = {
.dac_info = revo71_surround,
};
-static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
.caddr = 3,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -262,7 +262,7 @@ static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_revo51 __devinitdata = {
+static struct snd_akm4xxx akm_revo51 __devinitdata = {
.type = SND_AK4358,
.num_dacs = 6,
.ops = {
@@ -271,7 +271,7 @@ static const struct snd_akm4xxx akm_revo51 __devinitdata = {
.dac_info = revo51_dac,
};
-static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
.caddr = 2,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -283,13 +283,13 @@ static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
.mask_flags = 0,
};
-static const struct snd_akm4xxx akm_revo51_adc __devinitdata = {
+static struct snd_akm4xxx akm_revo51_adc __devinitdata = {
.type = SND_AK5365,
.num_adcs = 2,
.adc_info = revo51_adc,
};
-static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
.caddr = 2,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -324,7 +324,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
AK_DAC("PCM Playback Volume", 2)
};
-static const struct snd_akm4xxx akm_ap192 __devinitdata = {
+static struct snd_akm4xxx akm_ap192 __devinitdata = {
.type = SND_AK4358,
.num_dacs = 2,
.ops = {
@@ -333,7 +333,7 @@ static const struct snd_akm4xxx akm_ap192 __devinitdata = {
.dac_info = ap192_dac,
};
-static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {
.caddr = 2,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -405,7 +405,7 @@ static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
return data;
}
-static unsigned char ap192_4wire_start(struct snd_ice1712 *ice)
+static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)
{
unsigned int tmp;
@@ -454,7 +454,7 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
return data;
}
-static int ap192_ak4114_init(struct snd_ice1712 *ice)
+static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice)
{
static const unsigned char ak4114_init_vals[] = {
AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
@@ -582,7 +582,7 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice)
}
/* entry point */
-const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
{
.subvendor = VT1724_SUBDEVICE_REVOLUTION71,
.name = "M Audio Revolution-7.1",
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h
index 2a24488fad8..a3ba425911c 100644
--- a/sound/pci/ice1712/revo.h
+++ b/sound/pci/ice1712/revo.h
@@ -34,7 +34,7 @@
#define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236
/* entry point */
-extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[];
+extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
/*
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index 72b060d63c2..239524158fe 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -56,7 +56,7 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice)
/* EEPROM image */
-static const unsigned char k8x800_eeprom[] __devinitdata = {
+static unsigned char k8x800_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */
[ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */
[ICE_EEP2_I2S] = 0x00, /* - */
@@ -72,7 +72,7 @@ static const unsigned char k8x800_eeprom[] __devinitdata = {
[ICE_EEP2_GPIO_STATE2] = 0x00, /* - */
};
-static const unsigned char sn25p_eeprom[] __devinitdata = {
+static unsigned char sn25p_eeprom[] __devinitdata = {
[ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */
[ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */
[ICE_EEP2_I2S] = 0x00, /* - */
@@ -90,7 +90,7 @@ static const unsigned char sn25p_eeprom[] __devinitdata = {
/* entry point */
-const struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
{
.subvendor = VT1720_SUBDEVICE_K8X800,
.name = "Albatron K8X800 Pro II",
diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h
index 70af3ad64a5..0b1b0ee1bea 100644
--- a/sound/pci/ice1712/vt1720_mobo.h
+++ b/sound/pci/ice1712/vt1720_mobo.h
@@ -36,6 +36,6 @@
#define VT1720_SUBDEVICE_9CJS 0x0f272327
#define VT1720_SUBDEVICE_SN25P 0x97123650
-extern const struct snd_ice1712_card_info snd_vt1720_mobo_cards[];
+extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[];
#endif /* __SOUND_VT1720_MOBO_H */
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index 4a706b16a0b..04e535c8542 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -409,7 +409,7 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
/*
* Control tabs
*/
-static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
+static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 7cf2dcb9d8d..202f720b34b 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2493,6 +2493,7 @@ static int intel8x0_resume(struct pci_dev *pci)
return -EIO;
}
pci_set_master(pci);
+ snd_intel8x0_chip_init(chip, 0);
if (request_irq(pci->irq, snd_intel8x0_interrupt,
IRQF_SHARED, card->shortname, chip)) {
printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
@@ -2502,7 +2503,6 @@ static int intel8x0_resume(struct pci_dev *pci)
}
chip->irq = pci->irq;
synchronize_irq(chip->irq);
- snd_intel8x0_chip_init(chip, 0);
/* re-initialize mixer stuff */
if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) {
@@ -2862,16 +2862,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
chip->int_sta_mask = int_sta_masks;
- /* request irq after initializaing int_sta_mask, etc */
- if (request_irq(pci->irq, snd_intel8x0_interrupt,
- IRQF_SHARED, card->shortname, chip)) {
- snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
- snd_intel8x0_free(chip);
- return -EBUSY;
- }
- chip->irq = pci->irq;
pci_set_master(pci);
- synchronize_irq(chip->irq);
switch(chip->device_type) {
case DEVICE_INTEL_ICH4:
@@ -2901,6 +2892,15 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
return err;
}
+ /* request irq after initializaing int_sta_mask, etc */
+ if (request_irq(pci->irq, snd_intel8x0_interrupt,
+ IRQF_SHARED, card->shortname, chip)) {
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+ snd_intel8x0_free(chip);
+ return -EBUSY;
+ }
+ chip->irq = pci->irq;
+
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
snd_intel8x0_free(chip);
return err;
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 21d0899ac38..5338243fb03 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -264,9 +264,7 @@ enum MonitorModeSelector {
#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
// from the card after sending a command.
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
#include "korg1212-firmware.h"
static const struct firmware static_dsp_code = {
.data = (u8 *)dspCode,
@@ -418,6 +416,9 @@ struct snd_korg1212 {
MODULE_DESCRIPTION("korg1212");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}");
+#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("korg/k1212.dsp");
+#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -2342,26 +2343,25 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
offsetof(struct KorgSharedBuffer, AdatTimeCode);
+#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+ dsp_code = &static_dsp_code;
+#else
err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
if (err < 0) {
release_firmware(dsp_code);
-#ifdef FIRMWARE_IN_THE_KERNEL
- dsp_code = &static_dsp_code;
-#else
snd_printk(KERN_ERR "firmware not available\n");
snd_korg1212_free(korg1212);
return err;
-#endif
}
+#endif
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
dsp_code->size, &korg1212->dma_dsp) < 0) {
snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
snd_korg1212_free(korg1212);
-#ifdef FIRMWARE_IN_THE_KERNEL
- if (dsp_code != &static_dsp_code)
+#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+ release_firmware(dsp_code);
#endif
- release_firmware(dsp_code);
return -ENOMEM;
}
@@ -2371,10 +2371,9 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
-#ifdef FIRMWARE_IN_THE_KERNEL
- if (dsp_code != &static_dsp_code)
+#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL
+ release_firmware(dsp_code);
#endif
- release_firmware(dsp_code);
rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 4526904e3f8..8a5ff1cb536 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -59,6 +59,10 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI},"
"{ESS,Allegro PCI},"
"{ESS,Allegro-1 PCI},"
"{ESS,Canyon3D-2/LE PCI}}");
+#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw");
+MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw");
+#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -2101,9 +2105,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
}
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
/*
* DSP Code images
@@ -2242,7 +2244,7 @@ static const struct firmware assp_minisrc = {
.size = sizeof assp_minisrc_image
};
-#endif /* FIRMWARE_IN_THE_KERNEL */
+#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */
#ifdef __LITTLE_ENDIAN
static inline void snd_m3_convert_from_le(const struct firmware *fw) { }
@@ -2257,6 +2259,8 @@ static void snd_m3_convert_from_le(const struct firmware *fw)
}
#endif
+#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */
+
/*
* initialize ASSP
@@ -2550,14 +2554,10 @@ static int snd_m3_free(struct snd_m3 *chip)
if (chip->iobase)
pci_release_regions(chip->pci);
-#ifdef FIRMWARE_IN_THE_KERNEL
- if (chip->assp_kernel_image != &assp_kernel)
+#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+ release_firmware(chip->assp_kernel_image);
+ release_firmware(chip->assp_minisrc_image);
#endif
- release_firmware(chip->assp_kernel_image);
-#ifdef FIRMWARE_IN_THE_KERNEL
- if (chip->assp_minisrc_image != &assp_minisrc)
-#endif
- release_firmware(chip->assp_minisrc_image);
pci_disable_device(chip->pci);
kfree(chip);
@@ -2747,29 +2747,29 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
return -ENOMEM;
}
+#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+ chip->assp_kernel_image = &assp_kernel;
+#else
err = request_firmware(&chip->assp_kernel_image,
"ess/maestro3_assp_kernel.fw", &pci->dev);
if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
- chip->assp_kernel_image = &assp_kernel;
-#else
snd_m3_free(chip);
return err;
-#endif
} else
snd_m3_convert_from_le(chip->assp_kernel_image);
+#endif
+#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL
+ chip->assp_minisrc_image = &assp_minisrc;
+#else
err = request_firmware(&chip->assp_minisrc_image,
"ess/maestro3_assp_minisrc.fw", &pci->dev);
if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
- chip->assp_minisrc_image = &assp_minisrc;
-#else
snd_m3_free(chip);
return err;
-#endif
} else
snd_m3_convert_from_le(chip->assp_minisrc_image);
+#endif
if ((err = pci_request_regions(pci, card->driver)) < 0) {
snd_m3_free(chip);
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index ca05075c67c..1d9232d2db3 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -565,6 +565,9 @@ int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
return 0;
}
+MODULE_FIRMWARE("mixart/miXart8.xlx");
+MODULE_FIRMWARE("mixart/miXart8.elf");
+MODULE_FIRMWARE("mixart/miXart8AES.xlx");
#else /* old style firmware loading */
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index d97413484ae..f7f6a687f03 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -638,22 +638,22 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
{
struct pcxhr_stream *stream;
- struct list_head *pos;
struct snd_pcm_substream *s;
- int i;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_printdd("SNDRV_PCM_TRIGGER_START\n");
- i = 0;
- snd_pcm_group_for_each(pos, subs) {
- s = snd_pcm_group_substream_entry(pos);
- stream = s->runtime->private_data;
- stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN;
- snd_pcm_trigger_done(s, subs);
- i++;
- }
- if (i==1) {
+ if (snd_pcm_stream_linked(subs)) {
+ struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+ snd_pcm_group_for_each_entry(s, subs) {
+ stream = s->runtime->private_data;
+ stream->status =
+ PCXHR_STREAM_STATUS_SCHEDULE_RUN;
+ snd_pcm_trigger_done(s, subs);
+ }
+ tasklet_hi_schedule(&chip->mgr->trigger_taskq);
+ } else {
+ stream = subs->runtime->private_data;
snd_printdd("Only one Substream %c %d\n",
stream->pipe->is_capture ? 'C' : 'P',
stream->pipe->first_audio);
@@ -665,15 +665,11 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
if (pcxhr_set_stream_state(stream))
return -EINVAL;
stream->status = PCXHR_STREAM_STATUS_RUNNING;
- } else {
- struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
- tasklet_hi_schedule(&chip->mgr->trigger_taskq);
}
break;
case SNDRV_PCM_TRIGGER_STOP:
snd_printdd("SNDRV_PCM_TRIGGER_STOP\n");
- snd_pcm_group_for_each(pos, subs) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, subs) {
stream = s->runtime->private_data;
stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP;
if (pcxhr_set_stream_state(stream))
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 369c19fea98..d55d8bc90ee 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -356,6 +356,12 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
return 0;
}
+MODULE_FIRMWARE("pcxhr/xi_1_882.dat");
+MODULE_FIRMWARE("pcxhr/xc_1_882.dat");
+MODULE_FIRMWARE("pcxhr/e321_512.e56");
+MODULE_FIRMWARE("pcxhr/b321_512.b56");
+MODULE_FIRMWARE("pcxhr/d321_512.d56");
+
#else /* old style firmware loading */
/* pcxhr hwdep interface id string */
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 952625dead5..8e5410483e6 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -117,6 +117,7 @@ MODULE_AUTHOR("Peter Gruber <nokos@gmx.net>");
MODULE_DESCRIPTION("riptide");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}");
+MODULE_FIRMWARE("riptide.hex");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 6bb7ac650ec..618653e2256 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1078,12 +1078,10 @@ static int
snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct rme32 *rme32 = snd_pcm_substream_chip(substream);
- struct list_head *pos;
struct snd_pcm_substream *s;
spin_lock(&rme32->lock);
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s != rme32->playback_substream &&
s != rme32->capture_substream)
continue;
@@ -1110,8 +1108,7 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
/* prefill playback buffer */
if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) {
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == rme32->playback_substream) {
s->ops->ack(s);
break;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 89b3c7ff503..3b3ef657f73 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -60,6 +60,12 @@ MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
"{RME HDSP-9652},"
"{RME HDSP-9632}}");
+#ifdef HDSP_FW_LOADER
+MODULE_FIRMWARE("multiface_firmware.bin");
+MODULE_FIRMWARE("multiface_firmware_rev11.bin");
+MODULE_FIRMWARE("digiface_firmware.bin");
+MODULE_FIRMWARE("digiface_firmware_rev11.bin");
+#endif
#define HDSP_MAX_CHANNELS 26
#define HDSP_MAX_DS_CHANNELS 14
@@ -275,6 +281,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
#define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0)
#define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1)
#define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
+/* RME says n = 104857600000000, but in the windows MADI driver, I see:
+ return 104857600000000 / rate; // 100 MHz
+ return 110100480000000 / rate; // 105 MHz
+*/
+#define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */
#define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask)
#define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1)
@@ -1001,11 +1012,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
else if (rate >= 56000)
rate /= 2;
- /* RME says n = 104857600000000, but in the windows MADI driver, I see:
-// return 104857600000000 / rate; // 100 MHz
- return 110100480000000 / rate; // 105 MHz
- */
- n = 104857600000000ULL; /* = 2^20 * 10^8 */
+ n = DDS_NUMERATOR;
div64_32(&n, rate, &r);
/* n should be less than 2^32 for being written to FREQ register */
snd_assert((n >> 32) == 0);
@@ -3085,11 +3092,83 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn
return 0;
}
+#define HDSP_DDS_OFFSET(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .index = xindex, \
+ .info = snd_hdsp_info_dds_offset, \
+ .get = snd_hdsp_get_dds_offset, \
+ .put = snd_hdsp_put_dds_offset \
+}
+
+static int hdsp_dds_offset(struct hdsp *hdsp)
+{
+ u64 n;
+ u32 r;
+ unsigned int dds_value = hdsp->dds_value;
+ int system_sample_rate = hdsp->system_sample_rate;
+
+ n = DDS_NUMERATOR;
+ /*
+ * dds_value = n / rate
+ * rate = n / dds_value
+ */
+ div64_32(&n, dds_value, &r);
+ if (system_sample_rate >= 112000)
+ n *= 4;
+ else if (system_sample_rate >= 56000)
+ n *= 2;
+ return ((int)n) - system_sample_rate;
+}
+
+static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
+{
+ int rate = hdsp->system_sample_rate + offset_hz;
+ hdsp_set_dds_value(hdsp, rate);
+ return 0;
+}
+
+static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = -5000;
+ uinfo->value.integer.max = 5000;
+ return 0;
+}
+
+static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+
+ ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
+ return 0;
+}
+
+static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ int change;
+ int val;
+
+ if (!snd_hdsp_use_is_exclusive(hdsp))
+ return -EBUSY;
+ val = ucontrol->value.enumerated.item[0];
+ spin_lock_irq(&hdsp->lock);
+ if (val != hdsp_dds_offset(hdsp))
+ change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
+ else
+ change = 0;
+ spin_unlock_irq(&hdsp->lock);
+ return change;
+}
+
static struct snd_kcontrol_new snd_hdsp_9632_controls[] = {
HDSP_DA_GAIN("DA Gain", 0),
HDSP_AD_GAIN("AD Gain", 0),
HDSP_PHONE_GAIN("Phones Gain", 0),
-HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0)
+HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0),
+HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0)
};
static struct snd_kcontrol_new snd_hdsp_controls[] = {
@@ -3780,11 +3859,9 @@ static int snd_hdsp_reset(struct snd_pcm_substream *substream)
else
runtime->status->hw_ptr = 0;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
struct snd_pcm_runtime *oruntime = other->runtime;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
oruntime->status->hw_ptr = runtime->status->hw_ptr;
break;
@@ -3933,10 +4010,8 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd)
other = hdsp->playback_substream;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
snd_pcm_trigger_done(s, substream);
if (cmd == SNDRV_PCM_TRIGGER_START)
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 6e95857e4e6..143185e7e4d 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -91,8 +91,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define HDSPM_controlRegister 64
#define HDSPM_interruptConfirmation 96
#define HDSPM_control2Reg 256 /* not in specs ???????? */
+#define HDSPM_freqReg 256 /* for AES32 */
#define HDSPM_midiDataOut0 352 /* just believe in old code */
#define HDSPM_midiDataOut1 356
+#define HDSPM_eeprom_wr 384 /* for AES32 */
/* DMA enable for 64 channels, only Bit 0 is relevant */
#define HDSPM_outputEnableBase 512 /* 512-767 input DMA */
@@ -389,9 +391,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
size is the same regardless of the number of channels, and
also the latency to use.
for one direction !!!
- => need to mupltiply by 2!!
*/
-#define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
+#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
/* revisions >= 230 indicate AES32 card */
@@ -484,28 +485,6 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = {
56, 57, 58, 59, 60, 61, 62, 63
};
-static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = {
- 0, 2, 4, 6, 8, 10, 12, 14,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 48, 50, 52, 54, 56, 58, 60, 62,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = {
- 0, 4, 8, 12, 16, 20, 24, 28,
- 32, 36, 40, 44, 48, 52, 56, 60
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1
-};
-
static struct pci_device_id snd_hdspm_ids[] __devinitdata = {
{
@@ -818,6 +797,27 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames)
return 0;
}
+static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
+{
+ u64 n;
+ u32 r;
+
+ if (rate >= 112000)
+ rate /= 4;
+ else if (rate >= 56000)
+ rate /= 2;
+
+ /* RME says n = 104857600000000, but in the windows MADI driver, I see:
+// return 104857600000000 / rate; // 100 MHz
+ return 110100480000000 / rate; // 105 MHz
+ */
+ //n = 104857600000000ULL; /* = 2^20 * 10^8 */
+ n = 110100480000000ULL; /* Value checked for AES32 and MADI */
+ div64_32(&n, rate, &r);
+ /* n should be less than 2^32 for being written to FREQ register */
+ snd_assert((n >> 32) == 0);
+ hdspm_write(hdspm, HDSPM_freqReg, (u32)n);
+}
/* dummy set rate lets see what happens */
static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
@@ -943,12 +943,16 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
hdspm->control_register |= rate_bits;
hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
- if (rate > 96000 /* 64000*/)
- hdspm->channel_map = channel_map_madi_qs;
- else if (rate > 48000)
- hdspm->channel_map = channel_map_madi_ds;
- else
- hdspm->channel_map = channel_map_madi_ss;
+ /* For AES32, need to set DDS value in FREQ register
+ For MADI, also apparently */
+ hdspm_set_dds_value(hdspm, rate);
+
+ if (hdspm->is_aes32 && rate != current_rate)
+ hdspm_write(hdspm, HDSPM_eeprom_wr, 0);
+
+ /* For AES32 and for MADI (at least rev 204), channel_map needs to
+ * always be channel_map_madi_ss, whatever the sample rate */
+ hdspm->channel_map = channel_map_madi_ss;
hdspm->system_sample_rate = rate;
@@ -3184,8 +3188,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
snd_iprintf(buffer,
- "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n",
- hdspm->control_register, hdspm->control2_register,
+ "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n",
+ hdspm->control_register,
status, status2, timecode);
snd_iprintf(buffer, "--- Settings ---\n");
@@ -3377,13 +3381,16 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+ if (!hdspm->is_aes32) {
+ /* No control2 register for AES32 */
#ifdef SNDRV_BIG_ENDIAN
- hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
+ hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
#else
- hdspm->control2_register = 0;
+ hdspm->control2_register = 0;
#endif
- hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
+ hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
+ }
hdspm_compute_period_size(hdspm);
/* silence everything */
@@ -3575,11 +3582,9 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream)
else
runtime->status->hw_ptr = 0;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
struct snd_pcm_runtime *oruntime = other->runtime;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
oruntime->status->hw_ptr =
runtime->status->hw_ptr;
@@ -3658,11 +3663,10 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
/* Memory allocation, takashi's method, dont know if we should spinlock */
/* malloc all buffer even if not enabled to get sure */
- /* malloc only needed bytes */
+ /* Update for MADI rev 204: we need to allocate for all channels,
+ * otherwise it doesn't work at 96kHz */
err =
- snd_pcm_lib_malloc_pages(substream,
- HDSPM_CHANNEL_BUFFER_BYTES *
- params_channels(params));
+ snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES);
if (err < 0)
return err;
@@ -3698,6 +3702,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
"playback" : "capture",
snd_pcm_sgbuf_get_addr(sgbuf, 0));
*/
+ /*
+ snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n",
+ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+ "playback" : "capture",
+ params_rate(params), params_channels(params),
+ params_buffer_size(params));
+ */
return 0;
}
@@ -3791,10 +3802,8 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
other = hdspm->playback_substream;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
snd_pcm_trigger_done(s, substream);
if (cmd == SNDRV_PCM_TRIGGER_START)
@@ -3904,16 +3913,16 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
struct snd_interval *r =
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (r->min > 48000) {
+ if (r->min > 48000 && r->max <= 96000) {
struct snd_interval t = {
- .min = 1,
+ .min = hdspm->ds_channels,
.max = hdspm->ds_channels,
.integer = 1,
};
return snd_interval_refine(c, &t);
} else if (r->max < 64000) {
struct snd_interval t = {
- .min = 1,
+ .min = hdspm->ss_channels,
.max = hdspm->ss_channels,
.integer = 1,
};
@@ -3931,14 +3940,14 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
struct snd_interval *r =
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- if (c->min <= hdspm->ss_channels) {
+ if (c->min >= hdspm->ss_channels) {
struct snd_interval t = {
.min = 32000,
.max = 48000,
.integer = 1,
};
return snd_interval_refine(r, &t);
- } else if (c->max > hdspm->ss_channels) {
+ } else if (c->max <= hdspm->ds_channels) {
struct snd_interval t = {
.min = 64000,
.max = 96000,
@@ -3950,13 +3959,39 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
return 0;
}
+static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+ unsigned int list[3];
+ struct hdspm *hdspm = rule->private;
+ struct snd_interval *c = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+ if (hdspm->is_aes32) {
+ list[0] = hdspm->qs_channels;
+ list[1] = hdspm->ds_channels;
+ list[2] = hdspm->ss_channels;
+ return snd_interval_list(c, 3, list, 0);
+ } else {
+ list[0] = hdspm->ds_channels;
+ list[1] = hdspm->ss_channels;
+ return snd_interval_list(c, 2, list, 0);
+ }
+}
+
+
+static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 };
+
+static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = {
+ .count = ARRAY_SIZE(hdspm_aes32_sample_rates),
+ .list = hdspm_aes32_sample_rates,
+ .mask = 0
+};
+
static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
{
struct hdspm *hdspm = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- snd_printdd("Open device substream %d\n", substream->stream);
-
spin_lock_irq(&hdspm->lock);
snd_pcm_set_sync(substream);
@@ -3977,14 +4012,21 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
&hw_constraints_period_sizes);
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdspm_hw_rule_channels_rate, hdspm,
- SNDRV_PCM_HW_PARAM_RATE, -1);
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_hdspm_hw_rule_rate_channels, hdspm,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
-
+ if (hdspm->is_aes32) {
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &hdspm_hw_constraints_aes32_sample_rates);
+ } else {
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ snd_hdspm_hw_rule_channels, hdspm,
+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ snd_hdspm_hw_rule_channels_rate, hdspm,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ snd_hdspm_hw_rule_rate_channels, hdspm,
+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+ }
return 0;
}
@@ -4024,14 +4066,21 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
&hw_constraints_period_sizes);
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- snd_hdspm_hw_rule_channels_rate, hdspm,
- SNDRV_PCM_HW_PARAM_RATE, -1);
-
- snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- snd_hdspm_hw_rule_rate_channels, hdspm,
- SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+ if (hdspm->is_aes32) {
+ snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &hdspm_hw_constraints_aes32_sample_rates);
+ } else {
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ snd_hdspm_hw_rule_channels, hdspm,
+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ snd_hdspm_hw_rule_channels_rate, hdspm,
+ SNDRV_PCM_HW_PARAM_RATE, -1);
+
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ snd_hdspm_hw_rule_rate_channels, hdspm,
+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+ }
return 0;
}
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index cc3bdececce..bd7dbd267ed 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -1992,11 +1992,9 @@ static int snd_rme9652_reset(struct snd_pcm_substream *substream)
else
runtime->status->hw_ptr = 0;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
struct snd_pcm_runtime *oruntime = other->runtime;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
oruntime->status->hw_ptr = runtime->status->hw_ptr;
break;
@@ -2140,10 +2138,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
other = rme9652->playback_substream;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
snd_pcm_trigger_done(s, substream);
if (cmd == SNDRV_PCM_TRIGGER_START)
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 3bff32167f6..7ca60627246 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -1540,7 +1540,6 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
{
struct snd_trident *trident = snd_pcm_substream_chip(substream);
- struct list_head *pos;
struct snd_pcm_substream *s;
unsigned int what, whati, capture_flag, spdif_flag;
struct snd_trident_voice *voice, *evoice;
@@ -1563,8 +1562,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream,
what = whati = capture_flag = spdif_flag = 0;
spin_lock(&trident->reg_lock);
val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) {
voice = s->runtime->private_data;
evoice = voice->extra;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index fd12674d039..ea861bceadd 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1998,9 +1998,7 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip)
}
}
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
#include "ymfpci_image.h"
@@ -2018,6 +2016,24 @@ static struct firmware snd_ymfpci_controller_1e_microcode = {
};
#endif
+#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
+static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
+{
+ chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
+ if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
+ chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
+ chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
+ chip->device_id == PCI_DEVICE_ID_YAMAHA_754)
+ chip->controller_microcode =
+ &snd_ymfpci_controller_1e_microcode;
+ else
+ chip->controller_microcode =
+ &snd_ymfpci_controller_microcode;
+ return 0;
+}
+
+#else /* use fw_loader */
+
#ifdef __LITTLE_ENDIAN
static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { }
#else
@@ -2046,13 +2062,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
err = -EINVAL;
}
}
- if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
- chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
-#else
+ if (err < 0)
return err;
-#endif
- }
is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
@@ -2069,18 +2080,17 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
err = -EINVAL;
}
}
- if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
- chip->controller_microcode =
- is_1e ? &snd_ymfpci_controller_1e_microcode
- : &snd_ymfpci_controller_microcode;
-#else
+ if (err < 0)
return err;
-#endif
- }
return 0;
}
+MODULE_FIRMWARE("yamaha/ds1_dsp.fw");
+MODULE_FIRMWARE("yamaha/ds1_ctrl.fw");
+MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw");
+
+#endif
+
static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
{
int i;
@@ -2259,15 +2269,10 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
pci_disable_device(chip->pci);
-#ifdef FIRMWARE_IN_THE_KERNEL
- if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode)
-#endif
- release_firmware(chip->dsp_microcode);
-#ifdef FIRMWARE_IN_THE_KERNEL
- if (chip->controller_microcode != &snd_ymfpci_controller_microcode &&
- chip->controller_microcode != &snd_ymfpci_controller_1e_microcode)
+#ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL
+ release_firmware(chip->dsp_microcode);
+ release_firmware(chip->controller_microcode);
#endif
- release_firmware(chip->controller_microcode);
kfree(chip);
return 0;
}
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 363bcb5f08e..c57e127d9cc 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -297,7 +297,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev)
/* find an empty slot from the card list */
for (i = 0; i < SNDRV_CARDS; i++) {
- if (! card_alloc & (1 << i))
+ if (!(card_alloc & (1 << i)))
break;
}
if (i >= SNDRV_CARDS) {
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index dccaa4be679..10cffc08718 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -2,31 +2,31 @@
# SoC audio configuration
#
-menu "SoC audio support"
+menu "System on Chip audio support"
depends on SND!=n
config SND_SOC_AC97_BUS
bool
config SND_SOC
- tristate "SoC audio support"
+ tristate "ALSA for SoC audio support"
depends on SND
select SND_PCM
---help---
- If you want SoC support, you should say Y here and also to the
- specific driver for your SoC below. You will also need to select the
- specific codec(s) attached to the SoC
+ If you want ASoC support, you should say Y here and also to the
+ specific driver for your SoC platform below.
+
+ ASoC provides power efficient ALSA support for embedded battery powered
+ SoC based systems like PDA's, Phones and Personal Media Players.
- This SoC audio support can also be built as a module. If so, the module
+ This ASoC audio support can also be built as a module. If so, the module
will be called snd-soc-core.
# All the supported Soc's
-menu "SoC Platforms"
-depends on SND_SOC
source "sound/soc/at91/Kconfig"
source "sound/soc/pxa/Kconfig"
-endmenu
+source "sound/soc/s3c24xx/Kconfig"
# Supported codecs
source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 98e6f49dafc..0ae2e49036f 100644
--- a/sound/soc/Makefile
+++ b/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/
+obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
index a5b2558916c..5cb93fd3a40 100644
--- a/sound/soc/at91/Kconfig
+++ b/sound/soc/at91/Kconfig
@@ -1,5 +1,3 @@
-menu "SoC Audio for the Atmel AT91"
-
config SND_AT91_SOC
tristate "SoC Audio for the Atmel AT91 System-on-Chip"
depends on ARCH_AT91 && SND_SOC
@@ -8,13 +6,13 @@ config SND_AT91_SOC
the AT91 SSC interface. You will also need
to select the audio interfaces to support below.
-config SND_AT91_SOC_I2S
+config SND_AT91_SOC_SSC
tristate
config SND_AT91_SOC_ETI_B1_WM8731
- tristate "SoC I2S Audio support for WM8731-based Endrelia ETI-B1 boards"
+ tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards"
depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1)
- select SND_AT91_SOC_I2S
+ select SND_AT91_SOC_SSC
select SND_SOC_WM8731
help
Say Y if you want to add support for SoC audio on WM8731-based
@@ -27,5 +25,3 @@ config SND_AT91_SOC_ETI_SLAVE
help
Say Y if you want to run with the AT91 SSC generating the BCLK
and LRC signals on Endrelia boards.
-
-endmenu
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
index b77b01ab202..f23da17cc32 100644
--- a/sound/soc/at91/Makefile
+++ b/sound/soc/at91/Makefile
@@ -1,9 +1,9 @@
# AT91 Platform Support
snd-soc-at91-objs := at91-pcm.o
-snd-soc-at91-i2s-objs := at91-i2s.o
+snd-soc-at91-ssc-objs := at91-ssc.o
obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
-obj-$(CONFIG_SND_AT91_SOC_I2S) += snd-soc-at91-i2s.o
+obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
# AT91 Machine Support
snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o
diff --git a/sound/soc/at91/at91-i2s.c b/sound/soc/at91/at91-ssc.c
index 9fc0c038888..3d4e32cff75 100644
--- a/sound/soc/at91/at91-i2s.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -1,5 +1,5 @@
/*
- * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver
+ * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver
*
* Author: Frank Mandarino <fmandarino@endrelia.com>
* Endrelia Technologies Inc.
@@ -25,6 +25,7 @@
#include <sound/driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <sound/soc.h>
@@ -33,10 +34,10 @@
#include <asm/arch/at91_ssc.h>
#include "at91-pcm.h"
-#include "at91-i2s.h"
+#include "at91-ssc.h"
#if 0
-#define DBG(x...) printk(KERN_DEBUG "at91-i2s:" x)
+#define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x)
#else
#define DBG(x...)
#endif
@@ -92,33 +93,33 @@ static struct at91_ssc_mask ssc_rx_mask = {
*/
static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
{{
- .name = "SSC0/I2S PCM Stereo out",
+ .name = "SSC0 PCM out",
.pdc = &pdc_tx_reg,
.mask = &ssc_tx_mask,
},
{
- .name = "SSC0/I2S PCM Stereo in",
+ .name = "SSC0 PCM in",
.pdc = &pdc_rx_reg,
.mask = &ssc_rx_mask,
}},
#if NUM_SSC_DEVICES == 3
{{
- .name = "SSC1/I2S PCM Stereo out",
+ .name = "SSC1 PCM out",
.pdc = &pdc_tx_reg,
.mask = &ssc_tx_mask,
},
{
- .name = "SSC1/I2S PCM Stereo in",
+ .name = "SSC1 PCM in",
.pdc = &pdc_rx_reg,
.mask = &ssc_rx_mask,
}},
{{
- .name = "SSC2/I2S PCM Stereo out",
+ .name = "SSC2 PCM out",
.pdc = &pdc_tx_reg,
.mask = &ssc_tx_mask,
},
{
- .name = "SSC1/I2S PCM Stereo in",
+ .name = "SSC2 PCM in",
.pdc = &pdc_rx_reg,
.mask = &ssc_rx_mask,
}},
@@ -151,33 +152,33 @@ static struct at91_ssc_info {
} ssc_info[NUM_SSC_DEVICES] = {
{
.name = "ssc0",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
.dir_mask = 0,
.initialized = 0,
},
#if NUM_SSC_DEVICES == 3
{
.name = "ssc1",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
.dir_mask = 0,
.initialized = 0,
},
{
.name = "ssc2",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
.dir_mask = 0,
.initialized = 0,
},
#endif
};
-static unsigned int at91_i2s_sysclk;
+static unsigned int at91_ssc_sysclk;
/*
* SSC interrupt handler. Passes PDC interrupts to the DMA
* interrupt handler in the PCM driver.
*/
-static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id)
+static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id)
{
struct at91_ssc_info *ssc_p = dev_id;
struct at91_pcm_dma_params *dma_params;
@@ -209,13 +210,13 @@ static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id)
/*
* Startup. Only that one substream allowed in each direction.
*/
-static int at91_i2s_startup(struct snd_pcm_substream *substream)
+static int at91_ssc_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
int dir_mask;
- DBG("i2s_startup: SSC_SR=0x%08lx\n",
+ DBG("ssc_startup: SSC_SR=0x%08lx\n",
at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
@@ -234,7 +235,7 @@ static int at91_i2s_startup(struct snd_pcm_substream *substream)
* Shutdown. Clear DMA parameters and shutdown the SSC if there
* are no other substreams open.
*/
-static void at91_i2s_shutdown(struct snd_pcm_substream *substream)
+static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
@@ -281,7 +282,7 @@ static void at91_i2s_shutdown(struct snd_pcm_substream *substream)
/*
* Record the SSC system clock rate.
*/
-static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
+static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
int clk_id, unsigned int freq, int dir)
{
/*
@@ -291,7 +292,7 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
*/
switch (clk_id) {
case AT91_SYSCLK_MCK:
- at91_i2s_sysclk = freq;
+ at91_ssc_sysclk = freq;
break;
default:
return -EINVAL;
@@ -303,14 +304,11 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
/*
* Record the DAI format for use in hw_params().
*/
-static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
+static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
unsigned int fmt)
{
struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
- if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S)
- return -EINVAL;
-
ssc_p->daifmt = fmt;
return 0;
}
@@ -318,7 +316,7 @@ static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
/*
* Record SSC clock dividers for use in hw_params().
*/
-static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
+static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
int div_id, int div)
{
struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
@@ -355,7 +353,7 @@ static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
/*
* Configure the SSC.
*/
-static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
+static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -391,20 +389,50 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
channels = params_channels(params);
/*
+ * Determine sample size in bits and the PDC increment.
+ */
+ switch(params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ bits = 8;
+ dma_params->pdc_xfer_size = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ bits = 16;
+ dma_params->pdc_xfer_size = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bits = 24;
+ dma_params->pdc_xfer_size = 4;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bits = 32;
+ dma_params->pdc_xfer_size = 4;
+ break;
+ default:
+ printk(KERN_WARNING "at91-ssc: unsupported PCM format");
+ return -EINVAL;
+ }
+
+ /*
* The SSC only supports up to 16-bit samples in I2S format, due
- * to the size of the Frame Mode Register FSLEN field. Also, I2S
- * implies signed data.
+ * to the size of the Frame Mode Register FSLEN field.
*/
- bits = 16;
- dma_params->pdc_xfer_size = 2;
+ if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
+ && bits > 16) {
+ printk(KERN_WARNING
+ "at91-ssc: sample size %d is too large for I2S\n", bits);
+ return -EINVAL;
+ }
/*
* Compute SSC register settings.
*/
- switch (ssc_p->daifmt) {
- case SND_SOC_DAIFMT_CBS_CFS:
+ switch (ssc_p->daifmt
+ & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
+
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
/*
- * SSC provides BCLK and LRC clocks.
+ * I2S format, SSC provides BCLK and LRC clocks.
*
* The SSC transmit and receive clocks are generated from the
* MCK divider, and the BCLK signal is output on the SSC TK line.
@@ -441,10 +469,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
| (((bits - 1) << 0) & AT91_SSC_DATALEN);
break;
- case SND_SOC_DAIFMT_CBM_CFM:
-
+ case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
/*
- * CODEC supplies BCLK and LRC clocks.
+ * I2S format, CODEC supplies BCLK and LRC clocks.
*
* The SSC transmit clock is obtained from the BCLK signal on
* on the TK line, and the SSC receive clock is generated from the
@@ -490,10 +517,51 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
| (((bits - 1) << 0) & AT91_SSC_DATALEN);
break;
- case SND_SOC_DAIFMT_CBS_CFM:
- case SND_SOC_DAIFMT_CBM_CFS:
+ case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
+ /*
+ * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
+ *
+ * The SSC transmit and receive clocks are generated from the
+ * MCK divider, and the BCLK signal is output on the SSC TK line.
+ */
+ rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
+ | (( 1 << 16) & AT91_SSC_STTDLY)
+ | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
+ | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
+ | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
+ | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
+
+ rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
+ | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
+ | (( 0 << 16) & AT91_SSC_FSLEN)
+ | (((channels - 1) << 8) & AT91_SSC_DATNB)
+ | (( 1 << 7) & AT91_SSC_MSBF)
+ | (( 0 << 5) & AT91_SSC_LOOP)
+ | (((bits - 1) << 0) & AT91_SSC_DATALEN);
+
+ tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
+ | (( 1 << 16) & AT91_SSC_STTDLY)
+ | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
+ | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
+ | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
+ | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
+
+ tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
+ | (( 0 << 23) & AT91_SSC_FSDEN)
+ | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
+ | (( 0 << 16) & AT91_SSC_FSLEN)
+ | (((channels - 1) << 8) & AT91_SSC_DATNB)
+ | (( 1 << 7) & AT91_SSC_MSBF)
+ | (( 0 << 5) & AT91_SSC_DATDEF)
+ | (((bits - 1) << 0) & AT91_SSC_DATALEN);
+
+
+
+ break;
+
+ case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
default:
- printk(KERN_WARNING "at91-i2s: unsupported DAI format 0x%x.\n",
+ printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n",
ssc_p->daifmt);
return -EINVAL;
break;
@@ -518,9 +586,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
- if ((ret = request_irq(ssc_p->ssc.pid, at91_i2s_interrupt,
+ if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt,
0, ssc_p->name, ssc_p)) < 0) {
- printk(KERN_WARNING "at91-i2s: request_irq failure\n");
+ printk(KERN_WARNING "at91-ssc: request_irq failure\n");
DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
@@ -546,7 +614,7 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
}
-static int at91_i2s_prepare(struct snd_pcm_substream *substream)
+static int at91_ssc_prepare(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
@@ -566,7 +634,7 @@ static int at91_i2s_prepare(struct snd_pcm_substream *substream)
#ifdef CONFIG_PM
-static int at91_i2s_suspend(struct platform_device *pdev,
+static int at91_ssc_suspend(struct platform_device *pdev,
struct snd_soc_cpu_dai *cpu_dai)
{
struct at91_ssc_info *ssc_p;
@@ -594,7 +662,7 @@ static int at91_i2s_suspend(struct platform_device *pdev,
return 0;
}
-static int at91_i2s_resume(struct platform_device *pdev,
+static int at91_ssc_resume(struct platform_device *pdev,
struct snd_soc_cpu_dai *cpu_dai)
{
struct at91_ssc_info *ssc_p;
@@ -620,102 +688,105 @@ static int at91_i2s_resume(struct platform_device *pdev,
}
#else
-#define at91_i2s_suspend NULL
-#define at91_i2s_resume NULL
+#define at91_ssc_suspend NULL
+#define at91_ssc_resume NULL
#endif
-#define AT91_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
SNDRV_PCM_RATE_96000)
-struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = {
- { .name = "at91_ssc0/i2s",
+#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
+ { .name = "at91-ssc0",
.id = 0,
- .type = SND_SOC_DAI_I2S,
- .suspend = at91_i2s_suspend,
- .resume = at91_i2s_resume,
+ .type = SND_SOC_DAI_PCM,
+ .suspend = at91_ssc_suspend,
+ .resume = at91_ssc_resume,
.playback = {
.channels_min = 1,
.channels_max = 2,
- .rates = AT91_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .rates = AT91_SSC_RATES,
+ .formats = AT91_SSC_FORMATS,},
.capture = {
.channels_min = 1,
.channels_max = 2,
- .rates = AT91_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .rates = AT91_SSC_RATES,
+ .formats = AT91_SSC_FORMATS,},
.ops = {
- .startup = at91_i2s_startup,
- .shutdown = at91_i2s_shutdown,
- .prepare = at91_i2s_prepare,
- .hw_params = at91_i2s_hw_params,},
+ .startup = at91_ssc_startup,
+ .shutdown = at91_ssc_shutdown,
+ .prepare = at91_ssc_prepare,
+ .hw_params = at91_ssc_hw_params,},
.dai_ops = {
- .set_sysclk = at91_i2s_set_dai_sysclk,
- .set_fmt = at91_i2s_set_dai_fmt,
- .set_clkdiv = at91_i2s_set_dai_clkdiv,},
+ .set_sysclk = at91_ssc_set_dai_sysclk,
+ .set_fmt = at91_ssc_set_dai_fmt,
+ .set_clkdiv = at91_ssc_set_dai_clkdiv,},
.private_data = &ssc_info[0].ssc,
},
#if NUM_SSC_DEVICES == 3
- { .name = "at91_ssc1/i2s",
+ { .name = "at91-ssc1",
.id = 1,
- .type = SND_SOC_DAI_I2S,
- .suspend = at91_i2s_suspend,
- .resume = at91_i2s_resume,
+ .type = SND_SOC_DAI_PCM,
+ .suspend = at91_ssc_suspend,
+ .resume = at91_ssc_resume,
.playback = {
.channels_min = 1,
.channels_max = 2,
- .rates = AT91_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .rates = AT91_SSC_RATES,
+ .formats = AT91_SSC_FORMATS,},
.capture = {
.channels_min = 1,
.channels_max = 2,
- .rates = AT91_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .rates = AT91_SSC_RATES,
+ .formats = AT91_SSC_FORMATS,},
.ops = {
- .startup = at91_i2s_startup,
- .shutdown = at91_i2s_shutdown,
- .prepare = at91_i2s_prepare,
- .hw_params = at91_i2s_hw_params,},
+ .startup = at91_ssc_startup,
+ .shutdown = at91_ssc_shutdown,
+ .prepare = at91_ssc_prepare,
+ .hw_params = at91_ssc_hw_params,},
.dai_ops = {
- .set_sysclk = at91_i2s_set_dai_sysclk,
- .set_fmt = at91_i2s_set_dai_fmt,
- .set_clkdiv = at91_i2s_set_dai_clkdiv,},
+ .set_sysclk = at91_ssc_set_dai_sysclk,
+ .set_fmt = at91_ssc_set_dai_fmt,
+ .set_clkdiv = at91_ssc_set_dai_clkdiv,},
.private_data = &ssc_info[1].ssc,
},
- { .name = "at91_ssc2/i2s",
+ { .name = "at91-ssc2",
.id = 2,
- .type = SND_SOC_DAI_I2S,
- .suspend = at91_i2s_suspend,
- .resume = at91_i2s_resume,
+ .type = SND_SOC_DAI_PCM,
+ .suspend = at91_ssc_suspend,
+ .resume = at91_ssc_resume,
.playback = {
.channels_min = 1,
.channels_max = 2,
- .rates = AT91_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .rates = AT91_SSC_RATES,
+ .formats = AT91_SSC_FORMATS,},
.capture = {
.channels_min = 1,
.channels_max = 2,
- .rates = AT91_I2S_RATES,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+ .rates = AT91_SSC_RATES,
+ .formats = AT91_SSC_FORMATS,},
.ops = {
- .startup = at91_i2s_startup,
- .shutdown = at91_i2s_shutdown,
- .prepare = at91_i2s_prepare,
- .hw_params = at91_i2s_hw_params,},
+ .startup = at91_ssc_startup,
+ .shutdown = at91_ssc_shutdown,
+ .prepare = at91_ssc_prepare,
+ .hw_params = at91_ssc_hw_params,},
.dai_ops = {
- .set_sysclk = at91_i2s_set_dai_sysclk,
- .set_fmt = at91_i2s_set_dai_fmt,
- .set_clkdiv = at91_i2s_set_dai_clkdiv,},
+ .set_sysclk = at91_ssc_set_dai_sysclk,
+ .set_fmt = at91_ssc_set_dai_fmt,
+ .set_clkdiv = at91_ssc_set_dai_clkdiv,},
.private_data = &ssc_info[2].ssc,
},
#endif
};
-EXPORT_SYMBOL_GPL(at91_i2s_dai);
+EXPORT_SYMBOL_GPL(at91_ssc_dai);
/* Module information */
MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
-MODULE_DESCRIPTION("AT91 I2S ASoC Interface");
+MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-i2s.h b/sound/soc/at91/at91-ssc.h
index f8a875ba0cc..b188f973df9 100644
--- a/sound/soc/at91/at91-i2s.h
+++ b/sound/soc/at91/at91-ssc.h
@@ -1,5 +1,5 @@
/*
- * at91-i2s.h - ALSA I2S interface for the Atmel AT91 SoC
+ * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC
*
* Author: Frank Mandarino <fmandarino@endrelia.com>
* Endrelia Technologies Inc.
@@ -10,18 +10,18 @@
* published by the Free Software Foundation.
*/
-#ifndef _AT91_I2S_H
-#define _AT91_I2S_H
+#ifndef _AT91_SSC_H
+#define _AT91_SSC_H
-/* I2S system clock ids */
+/* SSC system clock ids */
#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
-/* I2S divider ids */
+/* SSC divider ids */
#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */
#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
-extern struct snd_soc_cpu_dai at91_i2s_dai[];
+extern struct snd_soc_cpu_dai at91_ssc_dai[];
-#endif /* _AT91_I2S_H */
+#endif /* _AT91_SSC_H */
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
index 8179df3bb2f..820a676c56b 100644
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ b/sound/soc/at91/eti_b1_wm8731.c
@@ -40,7 +40,7 @@
#include "../codecs/wm8731.h"
#include "at91-pcm.h"
-#include "at91-i2s.h"
+#include "at91-ssc.h"
#if 0
#define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x)
@@ -248,15 +248,15 @@ static int eti_b1_wm8731_init(struct snd_soc_codec *codec)
static struct snd_soc_dai_link eti_b1_dai = {
.name = "WM8731",
- .stream_name = "WM8731",
- .cpu_dai = &at91_i2s_dai[1],
+ .stream_name = "WM8731 PCM",
+ .cpu_dai = &at91_ssc_dai[1],
.codec_dai = &wm8731_dai,
.init = eti_b1_wm8731_init,
.ops = &eti_b1_ops,
};
static struct snd_soc_machine snd_soc_machine_eti_b1 = {
- .name = "ETI_B1",
+ .name = "ETI_B1_WM8731",
.dai_link = &eti_b1_dai,
.num_links = 1,
};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index ec2a2787957..e5fb437b86e 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -10,6 +10,10 @@ config SND_SOC_WM8750
tristate
depends on SND_SOC
+config SND_SOC_WM8753
+ tristate
+ depends on SND_SOC
+
config SND_SOC_WM9712
tristate
depends on SND_SOC
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 3249a6e4f1d..e39a747a17c 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,9 +1,11 @@
snd-soc-ac97-objs := ac97.o
snd-soc-wm8731-objs := wm8731.o
snd-soc-wm8750-objs := wm8750.o
+snd-soc-wm8753-objs := wm8753.o
snd-soc-wm9712-objs := wm9712.o
obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
+obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 55bc55eb6e2..0cdef971cbd 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -60,6 +60,7 @@ static struct snd_soc_codec_dai ac97_dai = {
.ops = {
.prepare = ac97_prepare,},
};
+EXPORT_SYMBOL_GPL(ac97_dai);
static unsigned int ac97_read(struct snd_soc_codec *codec,
unsigned int reg)
diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h
index 930ddfc2321..2bf6d69fd06 100644
--- a/sound/soc/codecs/ac97.h
+++ b/sound/soc/codecs/ac97.h
@@ -14,5 +14,6 @@
#define __LINUX_SND_SOC_AC97_H
extern struct snd_soc_codec_device soc_codec_dev_ac97;
+extern struct snd_soc_codec_dai ac97_dai;
#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 7073e8e294f..28684eeda73 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -808,7 +808,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
codec->dai = &wm8750_dai;
codec->num_dai = 1;
codec->reg_cache_size = sizeof(wm8750_reg);
- codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KRENEL);
+ codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL);
if (codec->reg_cache == NULL)
return -ENOMEM;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
new file mode 100644
index 00000000000..efced934566
--- /dev/null
+++ b/sound/soc/codecs/wm8753.c
@@ -0,0 +1,1811 @@
+/*
+ * wm8753.c -- WM8753 ALSA Soc Audio driver
+ *
+ * Copyright 2003 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood
+ * liam.girdwood@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.
+ *
+ * Notes:
+ * The WM8753 is a low power, high quality stereo codec with integrated PCM
+ * codec designed for portable digital telephony applications.
+ *
+ * Dual DAI:-
+ *
+ * This driver support 2 DAI PCM's. This makes the default PCM available for
+ * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for
+ * voice.
+ *
+ * Please note that the voice PCM can be connected directly to a Bluetooth
+ * codec or GSM modem and thus cannot be read or written to, although it is
+ * available to be configured with snd_hw_params(), etc and kcontrols in the
+ * normal alsa manner.
+ *
+ * Fast DAI switching:-
+ *
+ * The driver can now fast switch between the DAI configurations via a
+ * an alsa kcontrol. This allows the PCM to remain open.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <asm/div64.h>
+
+#include "wm8753.h"
+
+#define AUDIO_NAME "wm8753"
+#define WM8753_VERSION "0.16"
+
+/*
+ * Debug
+ */
+
+#define WM8753_DEBUG 0
+
+#ifdef WM8753_DEBUG
+#define dbg(format, arg...) \
+ printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
+#else
+#define dbg(format, arg...) do {} while (0)
+#endif
+#define err(format, arg...) \
+ printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+ printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
+
+static int caps_charge = 2000;
+module_param(caps_charge, int, 0);
+MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
+
+static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
+ unsigned int mode);
+
+/* codec private data */
+struct wm8753_priv {
+ unsigned int sysclk;
+ unsigned int pcmclk;
+};
+
+/*
+ * wm8753 register cache
+ * We can't read the WM8753 register space when we
+ * are using 2 wire for device control, so we cache them instead.
+ */
+static const u16 wm8753_reg[] = {
+ 0x0008, 0x0000, 0x000a, 0x000a,
+ 0x0033, 0x0000, 0x0007, 0x00ff,
+ 0x00ff, 0x000f, 0x000f, 0x007b,
+ 0x0000, 0x0032, 0x0000, 0x00c3,
+ 0x00c3, 0x00c0, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0055,
+ 0x0005, 0x0050, 0x0055, 0x0050,
+ 0x0055, 0x0050, 0x0055, 0x0079,
+ 0x0079, 0x0079, 0x0079, 0x0079,
+ 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0097, 0x0097, 0x0000, 0x0004,
+ 0x0000, 0x0083, 0x0024, 0x01ba,
+ 0x0000, 0x0083, 0x0024, 0x01ba,
+ 0x0000, 0x0000
+};
+
+/*
+ * read wm8753 register cache
+ */
+static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1))
+ return -1;
+ return cache[reg - 1];
+}
+
+/*
+ * write wm8753 register cache
+ */
+static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ u16 *cache = codec->reg_cache;
+ if (reg < 1 || reg > 0x3f)
+ return;
+ cache[reg - 1] = value;
+}
+
+/*
+ * write to the WM8753 register space
+ */
+static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ u8 data[2];
+
+ /* data is
+ * D15..D9 WM8753 register offset
+ * D8...D0 register data
+ */
+ data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+ data[1] = value & 0x00ff;
+
+ wm8753_write_reg_cache (codec, reg, value);
+ if (codec->hw_write(codec->control_data, data, 2) == 2)
+ return 0;
+ else
+ return -EIO;
+}
+
+#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
+
+/*
+ * WM8753 Controls
+ */
+static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"};
+static const char *wm8753_base_filter[] =
+ {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz",
+ "100Hz @ 8kHz", "200Hz @ 8kHz"};
+static const char *wm8753_treble[] = {"8kHz", "4kHz"};
+static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"};
+static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"};
+static const char *wm8753_3d_func[] = {"Capture", "Playback"};
+static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"};
+static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"};
+static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"};
+static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"};
+static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"};
+static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2",
+ "Line 1", "Line 2"};
+static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"};
+static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"};
+static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"};
+static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
+static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2",
+ "Right PGA"};
+static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right",
+ "Left + Right"};
+static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"};
+static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"};
+static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
+static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"};
+static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left",
+ "Analogue Mix Right", "Digital Mono Mix"};
+static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k",
+ "82Hz @ 8kHz", "170Hz @ 8kHz"};
+static const char *wm8753_adc_filter[] = {"HiFi", "Voice"};
+static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"};
+static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"};
+static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC",
+ "Channel Swap"};
+
+static const struct soc_enum wm8753_enum[] = {
+SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base),
+SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter),
+SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble),
+SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func),
+SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type),
+SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func),
+SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc),
+SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc),
+SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp),
+SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix),
+SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux),
+SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux),
+SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel),
+SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux),
+SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src),
+SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3),
+SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4),
+SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel),
+SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel),
+SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc),
+SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp),
+SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter),
+SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel),
+SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode),
+SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel),
+};
+
+
+static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+
+ ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
+ return 0;
+}
+
+static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+
+ if (((mode &0xc) >> 2) == ucontrol->value.integer.value[0])
+ return 0;
+
+ mode &= 0xfff3;
+ mode |= (ucontrol->value.integer.value[0] << 2);
+
+ wm8753_write(codec, WM8753_IOCTL, mode);
+ wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]);
+ return 1;
+}
+
+static const struct snd_kcontrol_new wm8753_snd_controls[] = {
+SOC_DOUBLE_R("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0),
+
+SOC_DOUBLE_R("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0),
+
+SOC_DOUBLE_R("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V, 0, 127, 0),
+SOC_DOUBLE_R("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0, 127, 0),
+
+SOC_SINGLE("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0),
+
+SOC_DOUBLE_R("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7, 1),
+SOC_DOUBLE_R("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4, 7, 1),
+SOC_DOUBLE_R("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7, 1),
+
+SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7, 1, 0),
+SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7, 1, 0),
+
+SOC_SINGLE("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1),
+SOC_SINGLE("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1),
+SOC_SINGLE("Mono Voice Playback Volume", WM8753_MOUTM2, 4, 7, 1),
+SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
+
+SOC_ENUM("Bass Boost", wm8753_enum[0]),
+SOC_ENUM("Bass Filter", wm8753_enum[1]),
+SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1),
+
+SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1),
+SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
+
+SOC_DOUBLE("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1),
+SOC_SINGLE("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1),
+
+SOC_DOUBLE_R("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0),
+SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
+SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
+
+SOC_ENUM("Capture Filter Select", wm8753_enum[23]),
+SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]),
+SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1),
+
+SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0),
+SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0),
+SOC_ENUM("ALC Capture Function", wm8753_enum[3]),
+SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0),
+SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1),
+SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1),
+SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0),
+SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0),
+SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]),
+SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0),
+
+SOC_ENUM("3D Function", wm8753_enum[5]),
+SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]),
+SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]),
+SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0),
+SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0),
+
+SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0),
+SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0),
+
+SOC_ENUM("De-emphasis", wm8753_enum[8]),
+SOC_ENUM("Playback Mono Mix", wm8753_enum[9]),
+SOC_ENUM("Playback Phase", wm8753_enum[10]),
+
+SOC_SINGLE("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0),
+SOC_SINGLE("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0),
+
+SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai),
+
+SOC_ENUM("ADC Data Select", wm8753_enum[27]),
+};
+
+/* add non dapm controls */
+static int wm8753_add_controls(struct snd_soc_codec *codec)
+{
+ int err, i;
+
+ for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) {
+ err = snd_ctl_add(codec->card,
+ snd_soc_cnew(&wm8753_snd_controls[i],codec, NULL));
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+/*
+ * _DAPM_ Controls
+ */
+
+/* Left Mixer */
+static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = {
+SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0),
+SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0),
+SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0),
+SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0),
+};
+
+/* Right mixer */
+static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = {
+SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0),
+SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0),
+SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0),
+SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0),
+};
+
+/* Mono mixer */
+static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = {
+SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0),
+SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0),
+SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0),
+SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0),
+SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0),
+};
+
+/* Mono 2 Mux */
+static const struct snd_kcontrol_new wm8753_mono2_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[17]);
+
+/* Out 3 Mux */
+static const struct snd_kcontrol_new wm8753_out3_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[18]);
+
+/* Out 4 Mux */
+static const struct snd_kcontrol_new wm8753_out4_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[19]);
+
+/* ADC Mono Mix */
+static const struct snd_kcontrol_new wm8753_adc_mono_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[22]);
+
+/* Record mixer */
+static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = {
+SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0),
+SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0),
+SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0),
+};
+
+/* Left ADC mux */
+static const struct snd_kcontrol_new wm8753_adc_left_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[21]);
+
+/* Right ADC mux */
+static const struct snd_kcontrol_new wm8753_adc_right_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[20]);
+
+/* MIC mux */
+static const struct snd_kcontrol_new wm8753_mic_mux_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[16]);
+
+/* ALC mixer */
+static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = {
+SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0),
+SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0),
+SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0),
+SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0),
+};
+
+/* Left Line mux */
+static const struct snd_kcontrol_new wm8753_line_left_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[14]);
+
+/* Right Line mux */
+static const struct snd_kcontrol_new wm8753_line_right_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[13]);
+
+/* Mono Line mux */
+static const struct snd_kcontrol_new wm8753_line_mono_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[12]);
+
+/* Line mux and mixer */
+static const struct snd_kcontrol_new wm8753_line_mux_mix_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[11]);
+
+/* Rx mux and mixer */
+static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[15]);
+
+/* Mic Selector Mux */
+static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls =
+SOC_DAPM_ENUM("Route", wm8753_enum[25]);
+
+static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
+SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0),
+SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0,
+ &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)),
+SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0),
+SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0),
+SND_SOC_DAPM_OUTPUT("LOUT1"),
+SND_SOC_DAPM_OUTPUT("LOUT2"),
+SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0,
+ &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)),
+SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0),
+SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0),
+SND_SOC_DAPM_OUTPUT("ROUT1"),
+SND_SOC_DAPM_OUTPUT("ROUT2"),
+SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0,
+ &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)),
+SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0),
+SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
+SND_SOC_DAPM_OUTPUT("MONO1"),
+SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls),
+SND_SOC_DAPM_OUTPUT("MONO2"),
+SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0),
+SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls),
+SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
+SND_SOC_DAPM_OUTPUT("OUT3"),
+SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls),
+SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0),
+SND_SOC_DAPM_OUTPUT("OUT4"),
+SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0,
+ &wm8753_record_mixer_controls[0],
+ ARRAY_SIZE(wm8753_record_mixer_controls)),
+SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0),
+SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0,
+ &wm8753_adc_mono_controls),
+SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0,
+ &wm8753_adc_mono_controls),
+SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0,
+ &wm8753_adc_left_controls),
+SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0,
+ &wm8753_adc_right_controls),
+SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0,
+ &wm8753_mic_mux_controls),
+SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0,
+ &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)),
+SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0,
+ &wm8753_line_left_controls),
+SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0,
+ &wm8753_line_right_controls),
+SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0,
+ &wm8753_line_mono_controls),
+SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0,
+ &wm8753_line_mux_mix_controls),
+SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0,
+ &wm8753_rx_mux_mix_controls),
+SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0),
+SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0),
+SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0,
+ &wm8753_mic_sel_mux_controls),
+SND_SOC_DAPM_INPUT("LINE1"),
+SND_SOC_DAPM_INPUT("LINE2"),
+SND_SOC_DAPM_INPUT("RXP"),
+SND_SOC_DAPM_INPUT("RXN"),
+SND_SOC_DAPM_INPUT("ACIN"),
+SND_SOC_DAPM_OUTPUT("ACOP"),
+SND_SOC_DAPM_INPUT("MIC1N"),
+SND_SOC_DAPM_INPUT("MIC1"),
+SND_SOC_DAPM_INPUT("MIC2N"),
+SND_SOC_DAPM_INPUT("MIC2"),
+SND_SOC_DAPM_VMID("VREF"),
+};
+
+static const char *audio_map[][3] = {
+ /* left mixer */
+ {"Left Mixer", "Left Playback Switch", "Left DAC"},
+ {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
+ {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
+ {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
+
+ /* right mixer */
+ {"Right Mixer", "Right Playback Switch", "Right DAC"},
+ {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
+ {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
+ {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
+
+ /* mono mixer */
+ {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
+ {"Mono Mixer", "Left Playback Switch", "Left DAC"},
+ {"Mono Mixer", "Right Playback Switch", "Right DAC"},
+ {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
+ {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
+
+ /* left out */
+ {"Left Out 1", NULL, "Left Mixer"},
+ {"Left Out 2", NULL, "Left Mixer"},
+ {"LOUT1", NULL, "Left Out 1"},
+ {"LOUT2", NULL, "Left Out 2"},
+
+ /* right out */
+ {"Right Out 1", NULL, "Right Mixer"},
+ {"Right Out 2", NULL, "Right Mixer"},
+ {"ROUT1", NULL, "Right Out 1"},
+ {"ROUT2", NULL, "Right Out 2"},
+
+ /* mono 1 out */
+ {"Mono Out 1", NULL, "Mono Mixer"},
+ {"MONO1", NULL, "Mono Out 1"},
+
+ /* mono 2 out */
+ {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"},
+ {"Mono 2 Mux", "Inverted Mono 1", "MONO1"},
+ {"Mono 2 Mux", "Left", "Left Mixer"},
+ {"Mono 2 Mux", "Right", "Right Mixer"},
+ {"Mono Out 2", NULL, "Mono 2 Mux"},
+ {"MONO2", NULL, "Mono Out 2"},
+
+ /* out 3 */
+ {"Out3 Left + Right", NULL, "Left Mixer"},
+ {"Out3 Left + Right", NULL, "Right Mixer"},
+ {"Out3 Mux", "VREF", "VREF"},
+ {"Out3 Mux", "Left + Right", "Out3 Left + Right"},
+ {"Out3 Mux", "ROUT2", "ROUT2"},
+ {"Out 3", NULL, "Out3 Mux"},
+ {"OUT3", NULL, "Out 3"},
+
+ /* out 4 */
+ {"Out4 Mux", "VREF", "VREF"},
+ {"Out4 Mux", "Capture ST", "Capture ST Mixer"},
+ {"Out4 Mux", "LOUT2", "LOUT2"},
+ {"Out 4", NULL, "Out4 Mux"},
+ {"OUT4", NULL, "Out 4"},
+
+ /* record mixer */
+ {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
+ {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
+ {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
+
+ /* Mic/SideTone Mux */
+ {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"},
+ {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"},
+ {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"},
+ {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"},
+
+ /* Capture Left Mux */
+ {"Capture Left Mux", "PGA", "Left Capture Volume"},
+ {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
+ {"Capture Left Mux", "Line", "LINE1"},
+
+ /* Capture Right Mux */
+ {"Capture Right Mux", "PGA", "Right Capture Volume"},
+ {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
+ {"Capture Right Mux", "Sidetone", "Capture ST Mixer"},
+
+ /* Mono Capture mixer-mux */
+ {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
+ {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
+ {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
+ {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
+ {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"},
+ {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"},
+ {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"},
+ {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"},
+ {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"},
+
+ /* ADC */
+ {"Left ADC", NULL, "Capture Left Mixer"},
+ {"Right ADC", NULL, "Capture Right Mixer"},
+
+ /* Left Capture Volume */
+ {"Left Capture Volume", NULL, "ACIN"},
+
+ /* Right Capture Volume */
+ {"Right Capture Volume", NULL, "Mic 2 Volume"},
+
+ /* ALC Mixer */
+ {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
+ {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
+ {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
+ {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
+
+ /* Line Left Mux */
+ {"Line Left Mux", "Line 1", "LINE1"},
+ {"Line Left Mux", "Rx Mix", "Rx Mixer"},
+
+ /* Line Right Mux */
+ {"Line Right Mux", "Line 2", "LINE2"},
+ {"Line Right Mux", "Rx Mix", "Rx Mixer"},
+
+ /* Line Mono Mux */
+ {"Line Mono Mux", "Line Mix", "Line Mixer"},
+ {"Line Mono Mux", "Rx Mix", "Rx Mixer"},
+
+ /* Line Mixer/Mux */
+ {"Line Mixer", "Line 1 + 2", "LINE1"},
+ {"Line Mixer", "Line 1 - 2", "LINE1"},
+ {"Line Mixer", "Line 1 + 2", "LINE2"},
+ {"Line Mixer", "Line 1 - 2", "LINE2"},
+ {"Line Mixer", "Line 1", "LINE1"},
+ {"Line Mixer", "Line 2", "LINE2"},
+
+ /* Rx Mixer/Mux */
+ {"Rx Mixer", "RXP - RXN", "RXP"},
+ {"Rx Mixer", "RXP + RXN", "RXP"},
+ {"Rx Mixer", "RXP - RXN", "RXN"},
+ {"Rx Mixer", "RXP + RXN", "RXN"},
+ {"Rx Mixer", "RXP", "RXP"},
+ {"Rx Mixer", "RXN", "RXN"},
+
+ /* Mic 1 Volume */
+ {"Mic 1 Volume", NULL, "MIC1N"},
+ {"Mic 1 Volume", NULL, "Mic Selection Mux"},
+
+ /* Mic 2 Volume */
+ {"Mic 2 Volume", NULL, "MIC2N"},
+ {"Mic 2 Volume", NULL, "MIC2"},
+
+ /* Mic Selector Mux */
+ {"Mic Selection Mux", "Mic 1", "MIC1"},
+ {"Mic Selection Mux", "Mic 2", "MIC2N"},
+ {"Mic Selection Mux", "Mic 3", "MIC2"},
+
+ /* ACOP */
+ {"ACOP", NULL, "ALC Mixer"},
+
+ /* terminator */
+ {NULL, NULL, NULL},
+};
+
+static int wm8753_add_widgets(struct snd_soc_codec *codec)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++)
+ snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]);
+
+ /* set up the WM8753 audio map */
+ 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_new_widgets(codec);
+ return 0;
+}
+
+/* PLL divisors */
+struct _pll_div {
+ u32 div2:1;
+ u32 n:4;
+ u32 k:24;
+};
+
+/* The size in bits of the pll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_PLL_SIZE ((1 << 22) * 10)
+
+static void pll_factors(struct _pll_div *pll_div, unsigned int target,
+ unsigned int source)
+{
+ u64 Kpart;
+ unsigned int K, Ndiv, Nmod;
+
+ Ndiv = target / source;
+ if (Ndiv < 6) {
+ source >>= 1;
+ pll_div->div2 = 1;
+ Ndiv = target / source;
+ } else
+ pll_div->div2 = 0;
+
+ if ((Ndiv < 6) || (Ndiv > 12))
+ printk(KERN_WARNING
+ "WM8753 N value outwith recommended range! N = %d\n",Ndiv);
+
+ pll_div->n = Ndiv;
+ Nmod = target % source;
+ Kpart = FIXED_PLL_SIZE * (long long)Nmod;
+
+ do_div(Kpart, source);
+
+ K = Kpart & 0xFFFFFFFF;
+
+ /* Check if we need to round */
+ if ((K % 10) >= 5)
+ K += 5;
+
+ /* Move down to proper range now rounding is done */
+ K /= 10;
+
+ pll_div->k = K;
+}
+
+static int wm8753_set_dai_pll(struct snd_soc_codec_dai *codec_dai,
+ int pll_id, unsigned int freq_in, unsigned int freq_out)
+{
+ u16 reg, enable;
+ int offset;
+ struct snd_soc_codec *codec = codec_dai->codec;
+
+ if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2)
+ return -ENODEV;
+
+ if (pll_id == WM8753_PLL1) {
+ offset = 0;
+ enable = 0x10;
+ reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
+ } else {
+ offset = 4;
+ enable = 0x8;
+ reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
+ }
+
+ if (!freq_in || !freq_out) {
+ /* disable PLL */
+ wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
+ wm8753_write(codec, WM8753_CLOCK, reg);
+ return 0;
+ } else {
+ u16 value = 0;
+ struct _pll_div pll_div;
+
+ pll_factors(&pll_div, freq_out * 8, freq_in);
+
+ /* set up N and K PLL divisor ratios */
+ /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
+ value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
+ wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
+
+ /* bits 8:0 = PLL_K[17:9] */
+ value = (pll_div.k & 0x03fe00) >> 9;
+ wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
+
+ /* bits 8:0 = PLL_K[8:0] */
+ value = pll_div.k & 0x0001ff;
+ wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
+
+ /* set PLL as input and enable */
+ wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
+ (pll_div.div2 << 3));
+ wm8753_write(codec, WM8753_CLOCK, reg | enable);
+ }
+ return 0;
+}
+
+struct _coeff_div {
+ u32 mclk;
+ u32 rate;
+ u8 sr:5;
+ u8 usb:1;
+};
+
+/* codec hifi mclk (after PLL) clock divider coefficients */
+static const struct _coeff_div coeff_div[] = {
+ /* 8k */
+ {12288000, 8000, 0x6, 0x0},
+ {11289600, 8000, 0x16, 0x0},
+ {18432000, 8000, 0x7, 0x0},
+ {16934400, 8000, 0x17, 0x0},
+ {12000000, 8000, 0x6, 0x1},
+
+ /* 11.025k */
+ {11289600, 11025, 0x18, 0x0},
+ {16934400, 11025, 0x19, 0x0},
+ {12000000, 11025, 0x19, 0x1},
+
+ /* 16k */
+ {12288000, 16000, 0xa, 0x0},
+ {18432000, 16000, 0xb, 0x0},
+ {12000000, 16000, 0xa, 0x1},
+
+ /* 22.05k */
+ {11289600, 22050, 0x1a, 0x0},
+ {16934400, 22050, 0x1b, 0x0},
+ {12000000, 22050, 0x1b, 0x1},
+
+ /* 32k */
+ {12288000, 32000, 0xc, 0x0},
+ {18432000, 32000, 0xd, 0x0},
+ {12000000, 32000, 0xa, 0x1},
+
+ /* 44.1k */
+ {11289600, 44100, 0x10, 0x0},
+ {16934400, 44100, 0x11, 0x0},
+ {12000000, 44100, 0x11, 0x1},
+
+ /* 48k */
+ {12288000, 48000, 0x0, 0x0},
+ {18432000, 48000, 0x1, 0x0},
+ {12000000, 48000, 0x0, 0x1},
+
+ /* 88.2k */
+ {11289600, 88200, 0x1e, 0x0},
+ {16934400, 88200, 0x1f, 0x0},
+ {12000000, 88200, 0x1f, 0x1},
+
+ /* 96k */
+ {12288000, 96000, 0xe, 0x0},
+ {18432000, 96000, 0xf, 0x0},
+ {12000000, 96000, 0xe, 0x1},
+};
+
+static int get_coeff(int mclk, int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
+ if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
+ return i;
+ }
+ return -EINVAL;
+}
+
+/*
+ * Clock after PLL and dividers
+ */
+static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct wm8753_priv *wm8753 = codec->private_data;
+
+ switch (freq) {
+ case 11289600:
+ case 12000000:
+ case 12288000:
+ case 16934400:
+ case 18432000:
+ if (clk_id == WM8753_MCLK) {
+ wm8753->sysclk = freq;
+ return 0;
+ } else if (clk_id == WM8753_PCMCLK) {
+ wm8753->pcmclk = freq;
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+}
+
+/*
+ * Set's ADC and Voice DAC format.
+ */
+static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ voice |= 0x0002;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ voice |= 0x0001;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ voice |= 0x0003;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ voice |= 0x0013;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wm8753_write(codec, WM8753_PCM, voice);
+ return 0;
+}
+
+/*
+ * Set PCM DAI bit size and sample rate.
+ */
+static int wm8753_pcm_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_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->codec;
+ struct wm8753_priv *wm8753 = codec->private_data;
+ u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
+ u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ voice |= 0x0004;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ voice |= 0x0008;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ voice |= 0x000c;
+ break;
+ }
+
+ /* sample rate */
+ if (params_rate(params) * 384 == wm8753->pcmclk)
+ srate |= 0x80;
+ wm8753_write(codec, WM8753_SRATE1, srate);
+
+ wm8753_write(codec, WM8753_PCM, voice);
+ return 0;
+}
+
+/*
+ * Set's PCM dai fmt and BCLK.
+ */
+static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 voice, ioctl;
+
+ voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
+ ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ ioctl |= 0x2;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ voice |= 0x0040;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ /* frame inversion not valid for DSP modes */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ voice |= 0x0080;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_RIGHT_J:
+ case SND_SOC_DAIFMT_LEFT_J:
+ voice &= ~0x0010;
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ voice |= 0x0090;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ voice |= 0x0080;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ voice |= 0x0010;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wm8753_write(codec, WM8753_PCM, voice);
+ wm8753_write(codec, WM8753_IOCTL, ioctl);
+ return 0;
+}
+
+static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai,
+ int div_id, int div)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 reg;
+
+ switch (div_id) {
+ case WM8753_PCMDIV:
+ reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
+ wm8753_write(codec, WM8753_CLOCK, reg | div);
+ break;
+ case WM8753_BCLKDIV:
+ reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
+ wm8753_write(codec, WM8753_SRATE2, reg | div);
+ break;
+ case WM8753_VXCLKDIV:
+ reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
+ wm8753_write(codec, WM8753_SRATE2, reg | div);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Set's HiFi DAC format.
+ */
+static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
+
+ /* interface format */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ hifi |= 0x0002;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ hifi |= 0x0001;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ hifi |= 0x0003;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ hifi |= 0x0013;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wm8753_write(codec, WM8753_HIFI, hifi);
+ return 0;
+}
+
+/*
+ * Set's I2S DAI format.
+ */
+static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 ioctl, hifi;
+
+ hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
+ ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
+
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ ioctl |= 0x1;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ hifi |= 0x0040;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* clock inversion */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ case SND_SOC_DAIFMT_DSP_B:
+ /* frame inversion not valid for DSP modes */
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ hifi |= 0x0080;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_RIGHT_J:
+ case SND_SOC_DAIFMT_LEFT_J:
+ hifi &= ~0x0010;
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ hifi |= 0x0090;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ hifi |= 0x0080;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ hifi |= 0x0010;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wm8753_write(codec, WM8753_HIFI, hifi);
+ wm8753_write(codec, WM8753_IOCTL, ioctl);
+ return 0;
+}
+
+/*
+ * Set PCM DAI bit size and sample rate.
+ */
+static int wm8753_i2s_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_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->codec;
+ struct wm8753_priv *wm8753 = codec->private_data;
+ u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
+ u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
+ int coeff;
+
+ /* is digital filter coefficient valid ? */
+ coeff = get_coeff(wm8753->sysclk, params_rate(params));
+ if (coeff < 0) {
+ printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
+ return coeff;
+ }
+ wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
+ coeff_div[coeff].usb);
+
+ /* bit size */
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ hifi |= 0x0004;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ hifi |= 0x0008;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ hifi |= 0x000c;
+ break;
+ }
+
+ wm8753_write(codec, WM8753_HIFI, hifi);
+ return 0;
+}
+
+static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 clock;
+
+ /* set clk source as pcmclk */
+ clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
+ wm8753_write(codec, WM8753_CLOCK, clock);
+
+ if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
+ return -EINVAL;
+ return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
+ return -EINVAL;
+ return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 clock;
+
+ /* set clk source as pcmclk */
+ clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
+ wm8753_write(codec, WM8753_CLOCK, clock);
+
+ if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
+ return -EINVAL;
+ return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ u16 clock;
+
+ /* set clk source as mclk */
+ clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
+ wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
+
+ if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
+ return -EINVAL;
+ if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
+ return -EINVAL;
+ return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
+}
+
+static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
+
+ /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
+ * make sure we check if they are not both active when we mute */
+ if (mute && dai->id == 1) {
+ if (!wm8753_dai[WM8753_DAI_VOICE].playback.active ||
+ !wm8753_dai[WM8753_DAI_HIFI].playback.active)
+ wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+ } else {
+ if (mute)
+ wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+ else
+ wm8753_write(codec, WM8753_DAC, mute_reg);
+ }
+
+ return 0;
+}
+
+static int wm8753_dapm_event(struct snd_soc_codec *codec, int event)
+{
+ u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
+
+ switch (event) {
+ case SNDRV_CTL_POWER_D0: /* full On */
+ /* set vmid to 50k and unmute dac */
+ wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
+ break;
+ case SNDRV_CTL_POWER_D1: /* partial On */
+ case SNDRV_CTL_POWER_D2: /* partial On */
+ /* set vmid to 5k for quick power up */
+ wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+ break;
+ case SNDRV_CTL_POWER_D3hot: /* Off, with power */
+ /* mute dac and set vmid to 500k, enable VREF */
+ wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+ break;
+ case SNDRV_CTL_POWER_D3cold: /* Off, without power */
+ wm8753_write(codec, WM8753_PWR1, 0x0001);
+ break;
+ }
+ codec->dapm_state = event;
+ return 0;
+}
+
+#define WM8753_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 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+#define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+/*
+ * The WM8753 supports upto 4 different and mutually exclusive DAI
+ * configurations. This gives 2 PCM's available for use, hifi and voice.
+ * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI
+ * is connected between the wm8753 and a BT codec or GSM modem.
+ *
+ * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI
+ * 2. Voice over HIFI DAI - HIFI disabled
+ * 3. Voice disabled - HIFI over HIFI
+ * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
+ */
+static const struct snd_soc_codec_dai wm8753_all_dai[] = {
+/* DAI HiFi mode 1 */
+{ .name = "WM8753 HiFi",
+ .id = 1,
+ .playback = {
+ .stream_name = "HiFi Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .capture = { /* dummy for fast DAI switching */
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .ops = {
+ .hw_params = wm8753_i2s_hw_params,},
+ .dai_ops = {
+ .digital_mute = wm8753_mute,
+ .set_fmt = wm8753_mode1h_set_dai_fmt,
+ .set_clkdiv = wm8753_set_dai_clkdiv,
+ .set_pll = wm8753_set_dai_pll,
+ .set_sysclk = wm8753_set_dai_sysclk,
+ },
+},
+/* DAI Voice mode 1 */
+{ .name = "WM8753 Voice",
+ .id = 1,
+ .playback = {
+ .stream_name = "Voice Playback",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .ops = {
+ .hw_params = wm8753_pcm_hw_params,},
+ .dai_ops = {
+ .digital_mute = wm8753_mute,
+ .set_fmt = wm8753_mode1v_set_dai_fmt,
+ .set_clkdiv = wm8753_set_dai_clkdiv,
+ .set_pll = wm8753_set_dai_pll,
+ .set_sysclk = wm8753_set_dai_sysclk,
+ },
+},
+/* DAI HiFi mode 2 - dummy */
+{ .name = "WM8753 HiFi",
+ .id = 2,
+},
+/* DAI Voice mode 2 */
+{ .name = "WM8753 Voice",
+ .id = 2,
+ .playback = {
+ .stream_name = "Voice Playback",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .ops = {
+ .hw_params = wm8753_pcm_hw_params,},
+ .dai_ops = {
+ .digital_mute = wm8753_mute,
+ .set_fmt = wm8753_mode2_set_dai_fmt,
+ .set_clkdiv = wm8753_set_dai_clkdiv,
+ .set_pll = wm8753_set_dai_pll,
+ .set_sysclk = wm8753_set_dai_sysclk,
+ },
+},
+/* DAI HiFi mode 3 */
+{ .name = "WM8753 HiFi",
+ .id = 3,
+ .playback = {
+ .stream_name = "HiFi Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .ops = {
+ .hw_params = wm8753_i2s_hw_params,},
+ .dai_ops = {
+ .digital_mute = wm8753_mute,
+ .set_fmt = wm8753_mode3_4_set_dai_fmt,
+ .set_clkdiv = wm8753_set_dai_clkdiv,
+ .set_pll = wm8753_set_dai_pll,
+ .set_sysclk = wm8753_set_dai_sysclk,
+ },
+},
+/* DAI Voice mode 3 - dummy */
+{ .name = "WM8753 Voice",
+ .id = 3,
+},
+/* DAI HiFi mode 4 */
+{ .name = "WM8753 HiFi",
+ .id = 4,
+ .playback = {
+ .stream_name = "HiFi Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8753_RATES,
+ .formats = WM8753_FORMATS,},
+ .ops = {
+ .hw_params = wm8753_i2s_hw_params,},
+ .dai_ops = {
+ .digital_mute = wm8753_mute,
+ .set_fmt = wm8753_mode3_4_set_dai_fmt,
+ .set_clkdiv = wm8753_set_dai_clkdiv,
+ .set_pll = wm8753_set_dai_pll,
+ .set_sysclk = wm8753_set_dai_sysclk,
+ },
+},
+/* DAI Voice mode 4 - dummy */
+{ .name = "WM8753 Voice",
+ .id = 4,
+},
+};
+
+struct snd_soc_codec_dai wm8753_dai[2];
+EXPORT_SYMBOL_GPL(wm8753_dai);
+
+static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode)
+{
+ if (mode < 4) {
+ int playback_active, capture_active, codec_active, pop_wait;
+ void *private_data;
+
+ playback_active = wm8753_dai[0].playback.active;
+ capture_active = wm8753_dai[0].capture.active;
+ codec_active = wm8753_dai[0].active;
+ private_data = wm8753_dai[0].private_data;
+ pop_wait = wm8753_dai[0].pop_wait;
+ wm8753_dai[0] = wm8753_all_dai[mode << 1];
+ wm8753_dai[0].playback.active = playback_active;
+ wm8753_dai[0].capture.active = capture_active;
+ wm8753_dai[0].active = codec_active;
+ wm8753_dai[0].private_data = private_data;
+ wm8753_dai[0].pop_wait = pop_wait;
+
+ playback_active = wm8753_dai[1].playback.active;
+ capture_active = wm8753_dai[1].capture.active;
+ codec_active = wm8753_dai[1].active;
+ private_data = wm8753_dai[1].private_data;
+ pop_wait = wm8753_dai[1].pop_wait;
+ wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1];
+ wm8753_dai[1].playback.active = playback_active;
+ wm8753_dai[1].capture.active = capture_active;
+ wm8753_dai[1].active = codec_active;
+ wm8753_dai[1].private_data = private_data;
+ wm8753_dai[1].pop_wait = pop_wait;
+ }
+ wm8753_dai[0].codec = codec;
+ wm8753_dai[1].codec = codec;
+}
+
+static void wm8753_work(struct work_struct *work)
+{
+ struct snd_soc_codec *codec =
+ container_of(work, struct snd_soc_codec, delayed_work.work);
+ wm8753_dapm_event(codec, codec->dapm_state);
+}
+
+static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->codec;
+
+ /* we only need to suspend if we are a valid card */
+ if(!codec->card)
+ return 0;
+
+ wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
+ return 0;
+}
+
+static int wm8753_resume(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->codec;
+ int i;
+ u8 data[2];
+ u16 *cache = codec->reg_cache;
+
+ /* we only need to resume if we are a valid card */
+ if(!codec->card)
+ return 0;
+
+ /* Sync reg_cache with the hardware */
+ for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
+ if (i + 1 == WM8753_RESET)
+ continue;
+ data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
+ data[1] = cache[i] & 0x00ff;
+ codec->hw_write(codec->control_data, data, 2);
+ }
+
+ wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
+
+ /* charge wm8753 caps */
+ if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) {
+ wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2);
+ codec->dapm_state = SNDRV_CTL_POWER_D0;
+ schedule_delayed_work(&codec->delayed_work,
+ msecs_to_jiffies(caps_charge));
+ }
+
+ return 0;
+}
+
+/*
+ * initialise the WM8753 driver
+ * register the mixer and dsp interfaces with the kernel
+ */
+static int wm8753_init(struct snd_soc_device *socdev)
+{
+ struct snd_soc_codec *codec = socdev->codec;
+ int reg, ret = 0;
+
+ codec->name = "WM8753";
+ codec->owner = THIS_MODULE;
+ codec->read = wm8753_read_reg_cache;
+ codec->write = wm8753_write;
+ codec->dapm_event = wm8753_dapm_event;
+ codec->dai = wm8753_dai;
+ codec->num_dai = 2;
+ codec->reg_cache_size = sizeof(wm8753_reg);
+ codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL);
+
+ if (codec->reg_cache == NULL)
+ return -ENOMEM;
+
+ wm8753_set_dai_mode(codec, 0);
+
+ wm8753_reset(codec);
+
+ /* register pcms */
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ printk(KERN_ERR "wm8753: failed to create pcms\n");
+ goto pcm_err;
+ }
+
+ /* charge output caps */
+ wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2);
+ codec->dapm_state = SNDRV_CTL_POWER_D3hot;
+ schedule_delayed_work(&codec->delayed_work,
+ msecs_to_jiffies(caps_charge));
+
+ /* set the update bits */
+ reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
+ wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
+ wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_LADC);
+ wm8753_write(codec, WM8753_LADC, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_RADC);
+ wm8753_write(codec, WM8753_RADC, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
+ wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
+ wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
+ wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
+ wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
+ wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
+ reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
+ wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
+
+ wm8753_add_controls(codec);
+ wm8753_add_widgets(codec);
+ ret = snd_soc_register_card(socdev);
+ if (ret < 0) {
+ printk(KERN_ERR "wm8753: failed to register card\n");
+ goto card_err;
+ }
+ return ret;
+
+card_err:
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+pcm_err:
+ kfree(codec->reg_cache);
+ return ret;
+}
+
+/* If the i2c layer weren't so broken, we could pass this kind of data
+ around */
+static struct snd_soc_device *wm8753_socdev;
+
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+
+/*
+ * WM8753 2 wire address is determined by GPIO5
+ * state during powerup.
+ * low = 0x1a
+ * high = 0x1b
+ */
+static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
+
+/* Magic definition of all other variables and things */
+I2C_CLIENT_INSMOD;
+
+static struct i2c_driver wm8753_i2c_driver;
+static struct i2c_client client_template;
+
+static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
+{
+ struct snd_soc_device *socdev = wm8753_socdev;
+ struct wm8753_setup_data *setup = socdev->codec_data;
+ struct snd_soc_codec *codec = socdev->codec;
+ struct i2c_client *i2c;
+ int ret;
+
+ if (addr != setup->i2c_address)
+ return -ENODEV;
+
+ client_template.adapter = adap;
+ client_template.addr = addr;
+
+ i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
+ if (i2c == NULL){
+ kfree(codec);
+ return -ENOMEM;
+ }
+ i2c_set_clientdata(i2c, codec);
+ codec->control_data = i2c;
+
+ ret = i2c_attach_client(i2c);
+ if (ret < 0) {
+ err("failed to attach codec at addr %x\n", addr);
+ goto err;
+ }
+
+ ret = wm8753_init(socdev);
+ if (ret < 0) {
+ err("failed to initialise WM8753\n");
+ goto err;
+ }
+
+ return ret;
+
+err:
+ kfree(codec);
+ kfree(i2c);
+ return ret;
+}
+
+static int wm8753_i2c_detach(struct i2c_client *client)
+{
+ struct snd_soc_codec *codec = i2c_get_clientdata(client);
+ i2c_detach_client(client);
+ kfree(codec->reg_cache);
+ kfree(client);
+ return 0;
+}
+
+static int wm8753_i2c_attach(struct i2c_adapter *adap)
+{
+ return i2c_probe(adap, &addr_data, wm8753_codec_probe);
+}
+
+/* corgi i2c codec control layer */
+static struct i2c_driver wm8753_i2c_driver = {
+ .driver = {
+ .name = "WM8753 I2C Codec",
+ .owner = THIS_MODULE,
+ },
+ .id = I2C_DRIVERID_WM8753,
+ .attach_adapter = wm8753_i2c_attach,
+ .detach_client = wm8753_i2c_detach,
+ .command = NULL,
+};
+
+static struct i2c_client client_template = {
+ .name = "WM8753",
+ .driver = &wm8753_i2c_driver,
+};
+#endif
+
+static int wm8753_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct wm8753_setup_data *setup;
+ struct snd_soc_codec *codec;
+ struct wm8753_priv *wm8753;
+ int ret = 0;
+
+ info("WM8753 Audio Codec %s", WM8753_VERSION);
+
+ setup = socdev->codec_data;
+ codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+ if (codec == NULL)
+ return -ENOMEM;
+
+ wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
+ if (wm8753 == NULL) {
+ kfree(codec);
+ return -ENOMEM;
+ }
+
+ codec->private_data = wm8753;
+ socdev->codec = codec;
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+ wm8753_socdev = socdev;
+ INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
+
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+ if (setup->i2c_address) {
+ normal_i2c[0] = setup->i2c_address;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+ ret = i2c_add_driver(&wm8753_i2c_driver);
+ if (ret != 0)
+ printk(KERN_ERR "can't add i2c driver");
+ }
+#else
+ /* Add other interfaces here */
+#endif
+ return ret;
+}
+
+/*
+ * This function forces any delayed work to be queued and run.
+ */
+static int run_delayed_work(struct delayed_work *dwork)
+{
+ int ret;
+
+ /* cancel any work waiting to be queued. */
+ ret = cancel_delayed_work(dwork);
+
+ /* if there was any work waiting then we run it now and
+ * wait for it's completion */
+ if (ret) {
+ schedule_delayed_work(dwork, 0);
+ flush_scheduled_work();
+ }
+ return ret;
+}
+
+/* power down chip */
+static int wm8753_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->codec;
+
+ if (codec->control_data)
+ wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
+ run_delayed_work(&codec->delayed_work);
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
+#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8753_i2c_driver);
+#endif
+ kfree(codec->private_data);
+ kfree(codec);
+
+ return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8753 = {
+ .probe = wm8753_probe,
+ .remove = wm8753_remove,
+ .suspend = wm8753_suspend,
+ .resume = wm8753_resume,
+};
+
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
+
+MODULE_DESCRIPTION("ASoC WM8753 driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
new file mode 100644
index 00000000000..95e2a1f5316
--- /dev/null
+++ b/sound/soc/codecs/wm8753.h
@@ -0,0 +1,126 @@
+/*
+ * wm8753.h -- audio driver for WM8753
+ *
+ * Copyright 2003 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood
+ * liam.girdwood@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.
+ *
+ */
+
+#ifndef _WM8753_H
+#define _WM8753_H
+
+/* WM8753 register space */
+
+#define WM8753_DAC 0x01
+#define WM8753_ADC 0x02
+#define WM8753_PCM 0x03
+#define WM8753_HIFI 0x04
+#define WM8753_IOCTL 0x05
+#define WM8753_SRATE1 0x06
+#define WM8753_SRATE2 0x07
+#define WM8753_LDAC 0x08
+#define WM8753_RDAC 0x09
+#define WM8753_BASS 0x0a
+#define WM8753_TREBLE 0x0b
+#define WM8753_ALC1 0x0c
+#define WM8753_ALC2 0x0d
+#define WM8753_ALC3 0x0e
+#define WM8753_NGATE 0x0f
+#define WM8753_LADC 0x10
+#define WM8753_RADC 0x11
+#define WM8753_ADCTL1 0x12
+#define WM8753_3D 0x13
+#define WM8753_PWR1 0x14
+#define WM8753_PWR2 0x15
+#define WM8753_PWR3 0x16
+#define WM8753_PWR4 0x17
+#define WM8753_ID 0x18
+#define WM8753_INTPOL 0x19
+#define WM8753_INTEN 0x1a
+#define WM8753_GPIO1 0x1b
+#define WM8753_GPIO2 0x1c
+#define WM8753_RESET 0x1f
+#define WM8753_RECMIX1 0x20
+#define WM8753_RECMIX2 0x21
+#define WM8753_LOUTM1 0x22
+#define WM8753_LOUTM2 0x23
+#define WM8753_ROUTM1 0x24
+#define WM8753_ROUTM2 0x25
+#define WM8753_MOUTM1 0x26
+#define WM8753_MOUTM2 0x27
+#define WM8753_LOUT1V 0x28
+#define WM8753_ROUT1V 0x29
+#define WM8753_LOUT2V 0x2a
+#define WM8753_ROUT2V 0x2b
+#define WM8753_MOUTV 0x2c
+#define WM8753_OUTCTL 0x2d
+#define WM8753_ADCIN 0x2e
+#define WM8753_INCTL1 0x2f
+#define WM8753_INCTL2 0x30
+#define WM8753_LINVOL 0x31
+#define WM8753_RINVOL 0x32
+#define WM8753_MICBIAS 0x33
+#define WM8753_CLOCK 0x34
+#define WM8753_PLL1CTL1 0x35
+#define WM8753_PLL1CTL2 0x36
+#define WM8753_PLL1CTL3 0x37
+#define WM8753_PLL1CTL4 0x38
+#define WM8753_PLL2CTL1 0x39
+#define WM8753_PLL2CTL2 0x3a
+#define WM8753_PLL2CTL3 0x3b
+#define WM8753_PLL2CTL4 0x3c
+#define WM8753_BIASCTL 0x3d
+#define WM8753_ADCTL2 0x3f
+
+struct wm8753_setup_data {
+ unsigned short i2c_address;
+};
+
+#define WM8753_PLL1 0
+#define WM8753_PLL2 1
+
+/* clock inputs */
+#define WM8753_MCLK 0
+#define WM8753_PCMCLK 1
+
+/* clock divider id's */
+#define WM8753_PCMDIV 0
+#define WM8753_BCLKDIV 1
+#define WM8753_VXCLKDIV 2
+
+/* PCM clock dividers */
+#define WM8753_PCM_DIV_1 (0 << 6)
+#define WM8753_PCM_DIV_3 (2 << 6)
+#define WM8753_PCM_DIV_5_5 (3 << 6)
+#define WM8753_PCM_DIV_2 (4 << 6)
+#define WM8753_PCM_DIV_4 (5 << 6)
+#define WM8753_PCM_DIV_6 (6 << 6)
+#define WM8753_PCM_DIV_8 (7 << 6)
+
+/* BCLK clock dividers */
+#define WM8753_BCLK_DIV_1 (0 << 3)
+#define WM8753_BCLK_DIV_2 (1 << 3)
+#define WM8753_BCLK_DIV_4 (2 << 3)
+#define WM8753_BCLK_DIV_8 (3 << 3)
+#define WM8753_BCLK_DIV_16 (4 << 3)
+
+/* VXCLK clock dividers */
+#define WM8753_VXCLK_DIV_1 (0 << 6)
+#define WM8753_VXCLK_DIV_2 (1 << 6)
+#define WM8753_VXCLK_DIV_4 (2 << 6)
+#define WM8753_VXCLK_DIV_8 (3 << 6)
+#define WM8753_VXCLK_DIV_16 (4 << 6)
+
+#define WM8753_DAI_HIFI 0
+#define WM8753_DAI_VOICE 1
+
+extern struct snd_soc_codec_dai wm8753_dai[2];
+extern struct snd_soc_codec_device soc_codec_dev_wm8753;
+
+#endif
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index ee7a691a9ba..264413a00ca 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -676,14 +676,13 @@ static int wm9712_soc_probe(struct platform_device *pdev)
codec = socdev->codec;
mutex_init(&codec->mutex);
- codec->reg_cache =
- kzalloc(sizeof(u16) * ARRAY_SIZE(wm9712_reg), GFP_KERNEL);
+ codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
+
if (codec->reg_cache == NULL) {
ret = -ENOMEM;
goto cache_err;
}
- memcpy(codec->reg_cache, wm9712_reg, sizeof(u16) * ARRAY_SIZE(wm9712_reg));
- codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm9712_reg);
+ codec->reg_cache_size = sizeof(wm9712_reg);
codec->reg_cache_step = 2;
codec->name = "WM9712";
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index b9ab3b8e1d3..a83e22937c2 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,5 +1,3 @@
-menu "SoC Audio for the Intel PXA2xx"
-
config SND_PXA2XX_SOC
tristate "SoC Audio for the Intel PXA2xx chip"
depends on ARCH_PXA && SND_SOC
@@ -55,5 +53,3 @@ config SND_PXA2XX_SOC_TOSA
help
Say Y if you want to add support for SoC audio on Sharp
Zaurus SL-C6000x models (Tosa).
-
-endmenu
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
new file mode 100644
index 00000000000..044a3712077
--- /dev/null
+++ b/sound/soc/s3c24xx/Kconfig
@@ -0,0 +1,10 @@
+config SND_S3C24XX_SOC
+ tristate "SoC Audio for the Samsung S3C24XX chips"
+ depends on ARCH_S3C2410 && SND_SOC
+ 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
+ to select the audio interfaces to support below.
+
+config SND_S3C24XX_SOC_I2S
+ tristate
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
new file mode 100644
index 00000000000..6f0fffcb30f
--- /dev/null
+++ b/sound/soc/s3c24xx/Makefile
@@ -0,0 +1,6 @@
+# S3c24XX Platform Support
+snd-soc-s3c24xx-objs := s3c24xx-pcm.o
+snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
+
+obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
+obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
new file mode 100644
index 00000000000..8ca314dc889
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -0,0 +1,441 @@
+/*
+ * s3c24xx-i2s.c -- ALSA Soc Audio Layer
+ *
+ * (c) 2006 Wolfson Microelectronics PLC.
+ * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ * (c) 2004-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ * 11th Dec 2006 Merged with Simtec driver
+ * 10th Nov 2006 Initial version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/regs-iis.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-clock.h>
+#include <asm/arch/audio.h>
+#include <asm/dma.h>
+#include <asm/arch/dma.h>
+
+#include "s3c24xx-pcm.h"
+#include "s3c24xx-i2s.h"
+
+#define S3C24XX_I2S_DEBUG 0
+#if S3C24XX_I2S_DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+static struct s3c2410_dma_client s3c24xx_dma_client_out = {
+ .name = "I2S PCM Stereo out"
+};
+
+static struct s3c2410_dma_client s3c24xx_dma_client_in = {
+ .name = "I2S PCM Stereo in"
+};
+
+static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = {
+ .client = &s3c24xx_dma_client_out,
+ .channel = DMACH_I2S_OUT,
+ .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ .dma_size = 2,
+};
+
+static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = {
+ .client = &s3c24xx_dma_client_in,
+ .channel = DMACH_I2S_IN,
+ .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ .dma_size = 2,
+};
+
+struct s3c24xx_i2s_info {
+ void __iomem *regs;
+ struct clk *iis_clk;
+};
+static struct s3c24xx_i2s_info s3c24xx_i2s;
+
+static void s3c24xx_snd_txctrl(int on)
+{
+ u32 iisfcon;
+ u32 iiscon;
+ u32 iismod;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
+ iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+ iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+
+ DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+
+ if (on) {
+ iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE;
+ iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN;
+ iiscon &= ~S3C2410_IISCON_TXIDLE;
+ iismod |= S3C2410_IISMOD_TXMODE;
+
+ writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+ writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
+ } else {
+ /* note, we have to disable the FIFOs otherwise bad things
+ * seem to happen when the DMA stops. According to the
+ * Samsung supplied kernel, this should allow the DMA
+ * engine and FIFOs to reset. If this isn't allowed, the
+ * DMA engine will simply freeze randomly.
+ */
+
+ iisfcon &= ~S3C2410_IISFCON_TXENABLE;
+ iisfcon &= ~S3C2410_IISFCON_TXDMA;
+ iiscon |= S3C2410_IISCON_TXIDLE;
+ iiscon &= ~S3C2410_IISCON_TXDMAEN;
+ iismod &= ~S3C2410_IISMOD_TXMODE;
+
+ writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
+ writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+ writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ }
+
+ DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+}
+
+static void s3c24xx_snd_rxctrl(int on)
+{
+ u32 iisfcon;
+ u32 iiscon;
+ u32 iismod;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
+ iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+ iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+
+ DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+
+ if (on) {
+ iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE;
+ iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN;
+ iiscon &= ~S3C2410_IISCON_RXIDLE;
+ iismod |= S3C2410_IISMOD_RXMODE;
+
+ writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+ writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
+ } else {
+ /* note, we have to disable the FIFOs otherwise bad things
+ * seem to happen when the DMA stops. According to the
+ * Samsung supplied kernel, this should allow the DMA
+ * engine and FIFOs to reset. If this isn't allowed, the
+ * DMA engine will simply freeze randomly.
+ */
+
+ iisfcon &= ~S3C2410_IISFCON_RXENABLE;
+ iisfcon &= ~S3C2410_IISFCON_RXDMA;
+ iiscon |= S3C2410_IISCON_RXIDLE;
+ iiscon &= ~S3C2410_IISCON_RXDMAEN;
+ iismod &= ~S3C2410_IISMOD_RXMODE;
+
+ writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON);
+ writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
+ writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ }
+
+ DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon);
+}
+
+/*
+ * Wait for the LR signal to allow synchronisation to the L/R clock
+ * from the codec. May only be needed for slave mode.
+ */
+static int s3c24xx_snd_lrsync(void)
+{
+ u32 iiscon;
+ unsigned long timeout = jiffies + msecs_to_jiffies(5);
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ while (1) {
+ iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+ if (iiscon & S3C2410_IISCON_LRINDEX)
+ break;
+
+ if (timeout < jiffies)
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+/*
+ * Check whether CPU is the master or slave
+ */
+static inline int s3c24xx_snd_is_clkmaster(void)
+{
+ DBG("Entered %s\n", __FUNCTION__);
+
+ return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1;
+}
+
+/*
+ * Set S3C24xx I2S DAI format
+ */
+static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai,
+ unsigned int fmt)
+{
+ u32 iismod;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+ DBG("hw_params r: IISMOD: %lx \n", iismod);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ iismod |= S3C2410_IISMOD_SLAVE;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_LEFT_J:
+ iismod |= S3C2410_IISMOD_MSB;
+ break;
+ case SND_SOC_DAIFMT_I2S:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ DBG("hw_params w: IISMOD: %lx \n", iismod);
+ return 0;
+}
+
+static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ u32 iismod;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
+ else
+ rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
+
+ /* Working copies of register */
+ iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+ DBG("hw_params r: IISMOD: %lx\n", iismod);
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S8:
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ iismod |= S3C2410_IISMOD_16BIT;
+ break;
+ }
+
+ writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ DBG("hw_params w: IISMOD: %lx\n", iismod);
+ return 0;
+}
+
+static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ int ret = 0;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (!s3c24xx_snd_is_clkmaster()) {
+ ret = s3c24xx_snd_lrsync();
+ if (ret)
+ goto exit_err;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ s3c24xx_snd_rxctrl(1);
+ else
+ s3c24xx_snd_txctrl(1);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ s3c24xx_snd_rxctrl(0);
+ else
+ s3c24xx_snd_txctrl(0);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+exit_err:
+ return ret;
+}
+
+/*
+ * Set S3C24xx Clock source
+ */
+static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ iismod &= ~S3C2440_IISMOD_MPLL;
+
+ switch (clk_id) {
+ case S3C24XX_CLKSRC_PCLK:
+ break;
+ case S3C24XX_CLKSRC_MPLL:
+ iismod |= S3C2440_IISMOD_MPLL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ return 0;
+}
+
+/*
+ * Set S3C24xx Clock dividers
+ */
+static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
+ int div_id, int div)
+{
+ u32 reg;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ switch (div_id) {
+ 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_BCLK:
+ reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS);
+ writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD);
+ break;
+ case S3C24XX_DIV_PRESCALER:
+ writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR);
+ reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
+ writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * To avoid duplicating clock code, allow machine driver to
+ * get the clockrate from here.
+ */
+u32 s3c24xx_i2s_get_clockrate(void)
+{
+ return clk_get_rate(s3c24xx_i2s.iis_clk);
+}
+EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate);
+
+static int s3c24xx_i2s_probe(struct platform_device *pdev)
+{
+ DBG("Entered %s\n", __FUNCTION__);
+
+ s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
+ if (s3c24xx_i2s.regs == NULL)
+ return -ENXIO;
+
+ s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis");
+ if (s3c24xx_i2s.iis_clk == NULL) {
+ DBG("failed to get iis_clock\n");
+ return -ENODEV;
+ }
+ clk_enable(s3c24xx_i2s.iis_clk);
+
+ /* Configure the I2S pins in correct mode */
+ s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);
+ s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK);
+ s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
+ s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
+ s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
+
+ writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON);
+
+ s3c24xx_snd_txctrl(0);
+ s3c24xx_snd_rxctrl(0);
+
+ return 0;
+}
+
+#define S3C24XX_I2S_RATES \
+ (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
+ SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+struct snd_soc_cpu_dai s3c24xx_i2s_dai = {
+ .name = "s3c24xx-i2s",
+ .id = 0,
+ .type = SND_SOC_DAI_I2S,
+ .probe = s3c24xx_i2s_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = S3C24XX_I2S_RATES,
+ .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = S3C24XX_I2S_RATES,
+ .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
+ .ops = {
+ .trigger = s3c24xx_i2s_trigger,
+ .hw_params = s3c24xx_i2s_hw_params,},
+ .dai_ops = {
+ .set_fmt = s3c24xx_i2s_set_fmt,
+ .set_clkdiv = s3c24xx_i2s_set_clkdiv,
+ .set_sysclk = s3c24xx_i2s_set_sysclk,
+ },
+};
+EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
+
+/* Module information */
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h
new file mode 100644
index 00000000000..537b4ecce8a
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.h
@@ -0,0 +1,37 @@
+/*
+ * s3c24xx-i2s.c -- ALSA Soc Audio Layer
+ *
+ * Copyright 2005 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 S3C24XXI2S_H_
+#define S3C24XXI2S_H_
+
+/* clock sources */
+#define S3C24XX_CLKSRC_PCLK 0
+#define S3C24XX_CLKSRC_MPLL 1
+
+/* Clock dividers */
+#define S3C24XX_DIV_MCLK 0
+#define S3C24XX_DIV_BCLK 1
+#define S3C24XX_DIV_PRESCALER 2
+
+/* prescaler */
+#define S3C24XX_PRESCALE(a,b) \
+ (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT))
+
+u32 s3c24xx_i2s_get_clockrate(void);
+
+extern struct snd_soc_cpu_dai s3c24xx_i2s_dai;
+
+#endif /*S3C24XXI2S_H_*/
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
new file mode 100644
index 00000000000..21dc6974d6a
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -0,0 +1,468 @@
+/*
+ * s3c24xx-pcm.c -- ALSA Soc Audio Layer
+ *
+ * (c) 2006 Wolfson Microelectronics PLC.
+ * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ * (c) 2004-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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
+ * 11th Dec 2006 Merged with Simtec driver
+ * 10th Nov 2006 Initial version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/audio.h>
+
+#include "s3c24xx-pcm.h"
+
+#define S3C24XX_PCM_DEBUG 0
+#if S3C24XX_PCM_DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+static const struct snd_pcm_hardware s3c24xx_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_U16_LE |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S8,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 128*1024,
+ .period_bytes_min = PAGE_SIZE,
+ .period_bytes_max = PAGE_SIZE*2,
+ .periods_min = 2,
+ .periods_max = 128,
+ .fifo_size = 32,
+};
+
+struct s3c24xx_runtime_data {
+ spinlock_t lock;
+ int state;
+ unsigned int dma_loaded;
+ unsigned int dma_limit;
+ unsigned int dma_period;
+ dma_addr_t dma_start;
+ dma_addr_t dma_pos;
+ dma_addr_t dma_end;
+ struct s3c24xx_pcm_dma_params *params;
+};
+
+/* s3c24xx_pcm_enqueue
+ *
+ * place a dma buffer onto the queue for the dma system
+ * to handle.
+*/
+static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ dma_addr_t pos = prtd->dma_pos;
+ int ret;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ while (prtd->dma_loaded < prtd->dma_limit) {
+ unsigned long len = prtd->dma_period;
+
+ DBG("dma_loaded: %d\n",prtd->dma_loaded);
+
+ if ((pos + len) > prtd->dma_end) {
+ len = prtd->dma_end - pos;
+ DBG(KERN_DEBUG "%s: corrected dma len %ld\n",
+ __FUNCTION__, len);
+ }
+
+ ret = s3c2410_dma_enqueue(prtd->params->channel,
+ substream, pos, len);
+
+ if (ret == 0) {
+ prtd->dma_loaded++;
+ pos += prtd->dma_period;
+ if (pos >= prtd->dma_end)
+ pos = prtd->dma_start;
+ } else
+ break;
+ }
+
+ prtd->dma_pos = pos;
+}
+
+static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
+ void *dev_id, int size,
+ enum s3c2410_dma_buffresult result)
+{
+ struct snd_pcm_substream *substream = dev_id;
+ struct s3c24xx_runtime_data *prtd;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR)
+ return;
+
+ prtd = substream->runtime->private_data;
+
+ if (substream)
+ snd_pcm_period_elapsed(substream);
+
+ spin_lock(&prtd->lock);
+ if (prtd->state & ST_RUNNING) {
+ prtd->dma_loaded--;
+ s3c24xx_pcm_enqueue(substream);
+ }
+
+ spin_unlock(&prtd->lock);
+}
+
+static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
+ unsigned long totbytes = params_buffer_bytes(params);
+ int ret=0;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ /* return if this is a bufferless transfer e.g.
+ * codec <--> BT codec or GSM modem -- lg FIXME */
+ if (!dma)
+ return 0;
+
+ /* prepare DMA */
+ prtd->params = dma;
+
+ DBG("params %p, client %p, channel %d\n", prtd->params,
+ prtd->params->client, prtd->params->channel);
+
+ ret = s3c2410_dma_request(prtd->params->channel,
+ prtd->params->client, NULL);
+
+ if (ret) {
+ DBG(KERN_ERR "failed to get dma channel\n");
+ return ret;
+ }
+
+ /* channel needs configuring for mem=>device, increment memory addr,
+ * sync to pclk, half-word transfers to the IIS-FIFO. */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ s3c2410_dma_devconfig(prtd->params->channel,
+ S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC |
+ S3C2410_DISRCC_APB, prtd->params->dma_addr);
+
+ s3c2410_dma_config(prtd->params->channel,
+ prtd->params->dma_size,
+ S3C2410_DCON_SYNC_PCLK |
+ S3C2410_DCON_HANDSHAKE);
+ } else {
+ s3c2410_dma_config(prtd->params->channel,
+ prtd->params->dma_size,
+ S3C2410_DCON_HANDSHAKE |
+ S3C2410_DCON_SYNC_PCLK);
+
+ s3c2410_dma_devconfig(prtd->params->channel,
+ S3C2410_DMASRC_HW, 0x3,
+ prtd->params->dma_addr);
+ }
+
+ s3c2410_dma_set_buffdone_fn(prtd->params->channel,
+ s3c24xx_audio_buffdone);
+
+ snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+ runtime->dma_bytes = totbytes;
+
+ spin_lock_irq(&prtd->lock);
+ prtd->dma_loaded = 0;
+ prtd->dma_limit = runtime->hw.periods_min;
+ prtd->dma_period = params_period_bytes(params);
+ prtd->dma_start = runtime->dma_addr;
+ prtd->dma_pos = prtd->dma_start;
+ prtd->dma_end = prtd->dma_start + totbytes;
+ spin_unlock_irq(&prtd->lock);
+
+ return 0;
+}
+
+static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ /* TODO - do we need to ensure DMA flushed */
+ snd_pcm_set_runtime_buffer(substream, NULL);
+
+ if (prtd->params) {
+ s3c2410_dma_free(prtd->params->channel, prtd->params->client);
+ prtd->params = NULL;
+ }
+
+ return 0;
+}
+
+static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ int ret = 0;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ /* return if this is a bufferless transfer e.g.
+ * codec <--> BT codec or GSM modem -- lg FIXME */
+ if (!prtd->params)
+ return 0;
+
+ /* flush the DMA channel */
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
+ prtd->dma_loaded = 0;
+ prtd->dma_pos = prtd->dma_start;
+
+ /* enqueue dma buffers */
+ s3c24xx_pcm_enqueue(substream);
+
+ return ret;
+}
+
+static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+ int ret = 0;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ spin_lock(&prtd->lock);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ prtd->state |= ST_RUNNING;
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ prtd->state &= ~ST_RUNNING;
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ spin_unlock(&prtd->lock);
+
+ return ret;
+}
+
+static snd_pcm_uframes_t
+ s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd = runtime->private_data;
+ unsigned long res;
+ dma_addr_t src, dst;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ spin_lock(&prtd->lock);
+ s3c2410_dma_getposition(prtd->params->channel, &src, &dst);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ res = dst - prtd->dma_start;
+ else
+ res = src - prtd->dma_start;
+
+ spin_unlock(&prtd->lock);
+
+ DBG("Pointer %x %x\n",src,dst);
+
+ /* we seem to be getting the odd error from the pcm library due
+ * to out-of-bounds pointers. this is maybe due to the dma engine
+ * not having loaded the new values for the channel before being
+ * callled... (todo - fix )
+ */
+
+ if (res >= snd_pcm_lib_buffer_bytes(substream)) {
+ if (res == snd_pcm_lib_buffer_bytes(substream))
+ res = 0;
+ }
+
+ return bytes_to_frames(substream->runtime, res);
+}
+
+static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware);
+
+ prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
+ if (prtd == NULL)
+ return -ENOMEM;
+
+ runtime->private_data = prtd;
+ return 0;
+}
+
+static int s3c24xx_pcm_close(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct s3c24xx_runtime_data *prtd = runtime->private_data;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ if (prtd)
+ kfree(prtd);
+ else
+ DBG("s3c24xx_pcm_close called with prtd == NULL\n");
+
+ return 0;
+}
+
+static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+ runtime->dma_area,
+ runtime->dma_addr,
+ runtime->dma_bytes);
+}
+
+static struct snd_pcm_ops s3c24xx_pcm_ops = {
+ .open = s3c24xx_pcm_open,
+ .close = s3c24xx_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = s3c24xx_pcm_hw_params,
+ .hw_free = s3c24xx_pcm_hw_free,
+ .prepare = s3c24xx_pcm_prepare,
+ .trigger = s3c24xx_pcm_trigger,
+ .pointer = s3c24xx_pcm_pointer,
+ .mmap = s3c24xx_pcm_mmap,
+};
+
+static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+{
+ struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+ struct snd_dma_buffer *buf = &substream->dma_buffer;
+ size_t size = s3c24xx_pcm_hardware.buffer_bytes_max;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ buf->dev.type = SNDRV_DMA_TYPE_DEV;
+ buf->dev.dev = pcm->card->dev;
+ buf->private_data = NULL;
+ buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+ &buf->addr, GFP_KERNEL);
+ if (!buf->area)
+ return -ENOMEM;
+ buf->bytes = size;
+ return 0;
+}
+
+static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
+{
+ struct snd_pcm_substream *substream;
+ struct snd_dma_buffer *buf;
+ int stream;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ for (stream = 0; stream < 2; stream++) {
+ substream = pcm->streams[stream].substream;
+ if (!substream)
+ continue;
+
+ buf = &substream->dma_buffer;
+ if (!buf->area)
+ continue;
+
+ dma_free_writecombine(pcm->card->dev, buf->bytes,
+ buf->area, buf->addr);
+ buf->area = NULL;
+ }
+}
+
+static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK;
+
+static int s3c24xx_pcm_new(struct snd_card *card,
+ struct snd_soc_codec_dai *dai, struct snd_pcm *pcm)
+{
+ int ret = 0;
+
+ DBG("Entered %s\n", __FUNCTION__);
+
+ if (!card->dev->dma_mask)
+ card->dev->dma_mask = &s3c24xx_pcm_dmamask;
+ if (!card->dev->coherent_dma_mask)
+ card->dev->coherent_dma_mask = 0xffffffff;
+
+ if (dai->playback.channels_min) {
+ ret = s3c24xx_pcm_preallocate_dma_buffer(pcm,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ if (ret)
+ goto out;
+ }
+
+ if (dai->capture.channels_min) {
+ ret = s3c24xx_pcm_preallocate_dma_buffer(pcm,
+ SNDRV_PCM_STREAM_CAPTURE);
+ if (ret)
+ goto out;
+ }
+ out:
+ return ret;
+}
+
+struct snd_soc_platform s3c24xx_soc_platform = {
+ .name = "s3c24xx-audio",
+ .pcm_ops = &s3c24xx_pcm_ops,
+ .pcm_new = s3c24xx_pcm_new,
+ .pcm_free = s3c24xx_pcm_free_dma_buffers,
+};
+
+EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
+
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c24xx-pcm.h
new file mode 100644
index 00000000000..0088c79822e
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.h
@@ -0,0 +1,31 @@
+/*
+ * s3c24xx-pcm.h --
+ *
+ * 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.
+ *
+ * ALSA PCM interface for the Samsung S3C24xx CPU
+ */
+
+#ifndef _S3C24XX_PCM_H
+#define _S3C24XX_PCM_H
+
+#define ST_RUNNING (1<<0)
+#define ST_OPENED (1<<1)
+
+struct s3c24xx_pcm_dma_params {
+ struct s3c2410_dma_client *client; /* stream identifier */
+ int channel; /* Channel ID */
+ dma_addr_t dma_addr;
+ int dma_size; /* Size of the DMA transfer */
+};
+
+#define S3C24XX_DAI_I2S 0
+
+/* platform data */
+extern struct snd_soc_platform s3c24xx_soc_platform;
+extern struct snd_ac97_bus_ops s3c24xx_ac97_ops;
+
+#endif
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7caf8c7b0ac..96bce55572a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -882,13 +882,15 @@ int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
if (wsink->id == snd_soc_dapm_input) {
if (wsource->id == snd_soc_dapm_micbias ||
wsource->id == snd_soc_dapm_mic ||
- wsink->id == snd_soc_dapm_line)
+ wsink->id == snd_soc_dapm_line ||
+ wsink->id == snd_soc_dapm_output)
wsink->ext = 1;
}
if (wsource->id == snd_soc_dapm_output) {
if (wsink->id == snd_soc_dapm_spk ||
wsink->id == snd_soc_dapm_hp ||
- wsink->id == snd_soc_dapm_line)
+ wsink->id == snd_soc_dapm_line ||
+ wsink->id == snd_soc_dapm_input)
wsource->ext = 1;
}
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 900a00de35f..dca0344cc1b 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -661,11 +661,9 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd)
{
unsigned int what = 0;
struct snd_pcm_substream *s;
- struct list_head *pos;
unsigned long flags;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == chip->playback_substream) {
what |= CS4231_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index f05d02f5b69..315360f3127 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -29,5 +29,33 @@ config SND_USB_USX2Y
To compile this driver as a module, choose M here: the module
will be called snd-usb-usx2y.
+config SND_USB_CAIAQ
+ tristate "Native Instruments USB audio devices"
+ depends on SND && USB
+ select SND_HWDEP
+ select SND_RAWMIDI
+ select SND_PCM
+ help
+ Say Y here to include support for caiaq USB audio interfaces,
+ namely:
+
+ * Native Instruments RigKontrol2
+ * Native Instruments Kore Controller
+ * Native Instruments Audio Kontrol 1
+ * Native Instruments Audio 8 DJ
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-usb-caiaq.
+
+config SND_USB_CAIAQ_INPUT
+ bool "enable input device for controllers"
+ depends on SND_USB_CAIAQ
+ help
+ Say Y here to support input controllers like buttons, knobs,
+ alpha dials and analog pedals on the following products:
+
+ * Native Instruments RigKontrol2
+ * Native Instruments Audio Kontrol 1
+
endmenu
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 2c1dc11a72e..aa252ef2ebf 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -9,4 +9,4 @@ snd-usb-lib-objs := usbmidi.o
obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o
obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o
-obj-$(CONFIG_SND) += usx2y/
+obj-$(CONFIG_SND) += usx2y/ caiaq/
diff --git a/sound/usb/caiaq/Makefile b/sound/usb/caiaq/Makefile
new file mode 100644
index 00000000000..455c8c58a1b
--- /dev/null
+++ b/sound/usb/caiaq/Makefile
@@ -0,0 +1,3 @@
+snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o
+
+obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o
diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c
new file mode 100644
index 00000000000..0414d766ba0
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-audio.c
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) 2006,2007 Daniel Mack, Karsten Wiese
+ *
+ * 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
+*/
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/spinlock.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+#include <linux/input.h>
+#endif
+
+#include "caiaq-device.h"
+#include "caiaq-audio.h"
+
+#define N_URBS 32
+#define CLOCK_DRIFT_TOLERANCE 5
+#define FRAMES_PER_URB 8
+#define BYTES_PER_FRAME 512
+#define CHANNELS_PER_STREAM 2
+#define BYTES_PER_SAMPLE 3
+#define BYTES_PER_SAMPLE_USB 4
+#define MAX_BUFFER_SIZE (128*1024)
+
+#define ENDPOINT_CAPTURE 2
+#define ENDPOINT_PLAYBACK 6
+
+#define MAKE_CHECKBYTE(dev,stream,i) \
+ (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1)
+
+static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = {
+ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER),
+ .formats = SNDRV_PCM_FMTBIT_S24_3BE,
+ .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_96000),
+ .rate_min = 44100,
+ .rate_max = 0, /* will overwrite later */
+ .channels_min = CHANNELS_PER_STREAM,
+ .channels_max = CHANNELS_PER_STREAM,
+ .buffer_bytes_max = MAX_BUFFER_SIZE,
+ .period_bytes_min = 4096,
+ .period_bytes_max = MAX_BUFFER_SIZE,
+ .periods_min = 1,
+ .periods_max = 1024,
+};
+
+static void
+activate_substream(struct snd_usb_caiaqdev *dev,
+ struct snd_pcm_substream *sub)
+{
+ if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dev->sub_playback[sub->number] = sub;
+ else
+ dev->sub_capture[sub->number] = sub;
+}
+
+static void
+deactivate_substream(struct snd_usb_caiaqdev *dev,
+ struct snd_pcm_substream *sub)
+{
+ if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dev->sub_playback[sub->number] = NULL;
+ else
+ dev->sub_capture[sub->number] = NULL;
+}
+
+static int
+all_substreams_zero(struct snd_pcm_substream **subs)
+{
+ int i;
+ for (i = 0; i < MAX_STREAMS; i++)
+ if (subs[i] != NULL)
+ return 0;
+ return 1;
+}
+
+static int stream_start(struct snd_usb_caiaqdev *dev)
+{
+ int i, ret;
+
+ debug("stream_start(%p)\n", dev);
+ spin_lock_irq(&dev->spinlock);
+ if (dev->streaming) {
+ spin_unlock_irq(&dev->spinlock);
+ return -EINVAL;
+ }
+
+ dev->input_panic = 0;
+ dev->output_panic = 0;
+ dev->first_packet = 1;
+ dev->streaming = 1;
+
+ for (i = 0; i < N_URBS; i++) {
+ ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC);
+ if (ret) {
+ log("unable to trigger initial read #%d! (ret = %d)\n",
+ i, ret);
+ dev->streaming = 0;
+ spin_unlock_irq(&dev->spinlock);
+ return -EPIPE;
+ }
+ }
+
+ spin_unlock_irq(&dev->spinlock);
+ return 0;
+}
+
+static void stream_stop(struct snd_usb_caiaqdev *dev)
+{
+ int i;
+
+ debug("stream_stop(%p)\n", dev);
+ if (!dev->streaming)
+ return;
+
+ dev->streaming = 0;
+ for (i = 0; i < N_URBS; i++) {
+ usb_unlink_urb(dev->data_urbs_in[i]);
+ usb_unlink_urb(dev->data_urbs_out[i]);
+ }
+}
+
+static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
+{
+ struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
+ debug("snd_usb_caiaq_substream_open(%p)\n", substream);
+ substream->runtime->hw = dev->pcm_info;
+ snd_pcm_limit_hw_rates(substream->runtime);
+ return 0;
+}
+
+static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
+{
+ struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
+
+ debug("snd_usb_caiaq_substream_close(%p)\n", substream);
+ if (all_substreams_zero(dev->sub_playback) &&
+ all_substreams_zero(dev->sub_capture)) {
+ /* when the last client has stopped streaming,
+ * all sample rates are allowed again */
+ stream_stop(dev);
+ dev->pcm_info.rates = dev->samplerates;
+ }
+
+ return 0;
+}
+
+static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
+ struct snd_pcm_hw_params *hw_params)
+{
+ debug("snd_usb_caiaq_pcm_hw_params(%p)\n", sub);
+ return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
+}
+
+static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
+{
+ struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+ debug("snd_usb_caiaq_pcm_hw_free(%p)\n", sub);
+ spin_lock_irq(&dev->spinlock);
+ deactivate_substream(dev, sub);
+ spin_unlock_irq(&dev->spinlock);
+ return snd_pcm_lib_free_pages(sub);
+}
+
+/* this should probably go upstream */
+#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
+#error "Change this table"
+#endif
+
+static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
+ 48000, 64000, 88200, 96000, 176400, 192000 };
+
+static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ int bytes_per_sample, bpp, ret, i;
+ int index = substream->number;
+ struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ debug("snd_usb_caiaq_pcm_prepare(%p)\n", substream);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1;
+ else
+ dev->audio_in_buf_pos[index] = 0;
+
+ if (dev->streaming)
+ return 0;
+
+ /* the first client that opens a stream defines the sample rate
+ * setting for all subsequent calls, until the last client closed. */
+ for (i=0; i < ARRAY_SIZE(rates); i++)
+ if (runtime->rate == rates[i])
+ dev->pcm_info.rates = 1 << i;
+
+ snd_pcm_limit_hw_rates(runtime);
+
+ bytes_per_sample = BYTES_PER_SAMPLE;
+ if (dev->spec.data_alignment == 2)
+ bytes_per_sample++;
+
+ bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
+ * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams;
+
+ ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate,
+ runtime->sample_bits, bpp);
+ if (ret)
+ return ret;
+
+ ret = stream_start(dev);
+ if (ret)
+ return ret;
+
+ dev->output_running = 0;
+ wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ);
+ if (!dev->output_running) {
+ stream_stop(dev);
+ return -EPIPE;
+ }
+
+ return 0;
+}
+
+static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
+{
+ struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ spin_lock(&dev->spinlock);
+ activate_substream(dev, sub);
+ spin_unlock(&dev->spinlock);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ spin_lock(&dev->spinlock);
+ deactivate_substream(dev, sub);
+ spin_unlock(&dev->spinlock);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static snd_pcm_uframes_t
+snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
+{
+ int index = sub->number;
+ struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+
+ if (dev->input_panic || dev->output_panic)
+ return SNDRV_PCM_POS_XRUN;
+
+ if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ return bytes_to_frames(sub->runtime,
+ dev->audio_out_buf_pos[index]);
+ else
+ return bytes_to_frames(sub->runtime,
+ dev->audio_in_buf_pos[index]);
+}
+
+/* operators for both playback and capture */
+static struct snd_pcm_ops snd_usb_caiaq_ops = {
+ .open = snd_usb_caiaq_substream_open,
+ .close = snd_usb_caiaq_substream_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_usb_caiaq_pcm_hw_params,
+ .hw_free = snd_usb_caiaq_pcm_hw_free,
+ .prepare = snd_usb_caiaq_pcm_prepare,
+ .trigger = snd_usb_caiaq_pcm_trigger,
+ .pointer = snd_usb_caiaq_pcm_pointer
+};
+
+static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev,
+ struct snd_pcm_substream **subs)
+{
+ int stream, pb, *cnt;
+ struct snd_pcm_substream *sub;
+
+ for (stream = 0; stream < dev->n_streams; stream++) {
+ sub = subs[stream];
+ if (!sub)
+ continue;
+
+ pb = frames_to_bytes(sub->runtime,
+ sub->runtime->period_size);
+ cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ &dev->period_out_count[stream] :
+ &dev->period_in_count[stream];
+
+ if (*cnt >= pb) {
+ snd_pcm_period_elapsed(sub);
+ *cnt %= pb;
+ }
+ }
+}
+
+static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev,
+ const struct urb *urb,
+ const struct usb_iso_packet_descriptor *iso)
+{
+ unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
+ struct snd_pcm_substream *sub;
+ int stream, i;
+
+ if (all_substreams_zero(dev->sub_capture))
+ return;
+
+ spin_lock(&dev->spinlock);
+
+ for (i = 0; i < iso->actual_length;) {
+ for (stream = 0; stream < dev->n_streams; stream++, i++) {
+ sub = dev->sub_capture[stream];
+ if (sub) {
+ struct snd_pcm_runtime *rt = sub->runtime;
+ char *audio_buf = rt->dma_area;
+ int sz = frames_to_bytes(rt, rt->buffer_size);
+ audio_buf[dev->audio_in_buf_pos[stream]++]
+ = usb_buf[i];
+ dev->period_in_count[stream]++;
+ if (dev->audio_in_buf_pos[stream] == sz)
+ dev->audio_in_buf_pos[stream] = 0;
+ }
+ }
+ }
+
+ spin_unlock(&dev->spinlock);
+}
+
+static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
+ const struct urb *urb,
+ const struct usb_iso_packet_descriptor *iso)
+{
+ unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
+ unsigned char check_byte;
+ struct snd_pcm_substream *sub;
+ int stream, i;
+
+ spin_lock(&dev->spinlock);
+
+ for (i = 0; i < iso->actual_length;) {
+ if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) {
+ for (stream = 0;
+ stream < dev->n_streams;
+ stream++, i++) {
+ if (dev->first_packet)
+ continue;
+
+ check_byte = MAKE_CHECKBYTE(dev, stream, i);
+
+ if ((usb_buf[i] & 0x3f) != check_byte)
+ dev->input_panic = 1;
+
+ if (usb_buf[i] & 0x80)
+ dev->output_panic = 1;
+ }
+ }
+ dev->first_packet = 0;
+
+ for (stream = 0; stream < dev->n_streams; stream++, i++) {
+ sub = dev->sub_capture[stream];
+ if (sub) {
+ struct snd_pcm_runtime *rt = sub->runtime;
+ char *audio_buf = rt->dma_area;
+ int sz = frames_to_bytes(rt, rt->buffer_size);
+ audio_buf[dev->audio_in_buf_pos[stream]++] =
+ usb_buf[i];
+ dev->period_in_count[stream]++;
+ if (dev->audio_in_buf_pos[stream] == sz)
+ dev->audio_in_buf_pos[stream] = 0;
+ }
+ }
+ }
+
+ spin_unlock(&dev->spinlock);
+}
+
+static void read_in_urb(struct snd_usb_caiaqdev *dev,
+ const struct urb *urb,
+ const struct usb_iso_packet_descriptor *iso)
+{
+ if (!dev->streaming)
+ return;
+
+ switch (dev->spec.data_alignment) {
+ case 0:
+ read_in_urb_mode0(dev, urb, iso);
+ break;
+ case 2:
+ read_in_urb_mode2(dev, urb, iso);
+ break;
+ }
+
+ if (dev->input_panic || dev->output_panic) {
+ debug("streaming error detected %s %s\n",
+ dev->input_panic ? "(input)" : "",
+ dev->output_panic ? "(output)" : "");
+ }
+
+ check_for_elapsed_periods(dev, dev->sub_capture);
+}
+
+static void fill_out_urb(struct snd_usb_caiaqdev *dev,
+ struct urb *urb,
+ const struct usb_iso_packet_descriptor *iso)
+{
+ unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
+ struct snd_pcm_substream *sub;
+ int stream, i;
+
+ spin_lock(&dev->spinlock);
+
+ for (i = 0; i < iso->length;) {
+ for (stream = 0; stream < dev->n_streams; stream++, i++) {
+ sub = dev->sub_playback[stream];
+ if (sub) {
+ struct snd_pcm_runtime *rt = sub->runtime;
+ char *audio_buf = rt->dma_area;
+ int sz = frames_to_bytes(rt, rt->buffer_size);
+ usb_buf[i] =
+ audio_buf[dev->audio_out_buf_pos[stream]];
+ dev->period_out_count[stream]++;
+ dev->audio_out_buf_pos[stream]++;
+ if (dev->audio_out_buf_pos[stream] == sz)
+ dev->audio_out_buf_pos[stream] = 0;
+ } else
+ usb_buf[i] = 0;
+ }
+
+ /* fill in the check bytes */
+ if (dev->spec.data_alignment == 2 &&
+ i % (dev->n_streams * BYTES_PER_SAMPLE_USB) ==
+ (dev->n_streams * CHANNELS_PER_STREAM))
+ for (stream = 0; stream < dev->n_streams; stream++, i++)
+ usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
+ }
+
+ spin_unlock(&dev->spinlock);
+ check_for_elapsed_periods(dev, dev->sub_playback);
+}
+
+static void read_completed(struct urb *urb)
+{
+ struct snd_usb_caiaq_cb_info *info = urb->context;
+ struct snd_usb_caiaqdev *dev;
+ struct urb *out;
+ int frame, len, send_it = 0, outframe = 0;
+
+ if (urb->status || !info)
+ return;
+
+ dev = info->dev;
+ if (!dev->streaming)
+ return;
+
+ out = dev->data_urbs_out[info->index];
+
+ /* read the recently received packet and send back one which has
+ * the same layout */
+ for (frame = 0; frame < FRAMES_PER_URB; frame++) {
+ if (urb->iso_frame_desc[frame].status)
+ continue;
+
+ len = urb->iso_frame_desc[outframe].actual_length;
+ out->iso_frame_desc[outframe].length = len;
+ out->iso_frame_desc[outframe].actual_length = 0;
+ out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame;
+
+ if (len > 0) {
+ fill_out_urb(dev, out, &out->iso_frame_desc[outframe]);
+ read_in_urb(dev, urb, &urb->iso_frame_desc[frame]);
+ send_it = 1;
+ }
+
+ outframe++;
+ }
+
+ if (send_it) {
+ out->number_of_packets = FRAMES_PER_URB;
+ out->transfer_flags = URB_ISO_ASAP;
+ usb_submit_urb(out, GFP_ATOMIC);
+ }
+
+ /* re-submit inbound urb */
+ for (frame = 0; frame < FRAMES_PER_URB; frame++) {
+ urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
+ urb->iso_frame_desc[frame].length = BYTES_PER_FRAME;
+ urb->iso_frame_desc[frame].actual_length = 0;
+ }
+
+ urb->number_of_packets = FRAMES_PER_URB;
+ urb->transfer_flags = URB_ISO_ASAP;
+ usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static void write_completed(struct urb *urb)
+{
+ struct snd_usb_caiaq_cb_info *info = urb->context;
+ struct snd_usb_caiaqdev *dev = info->dev;
+
+ if (!dev->output_running) {
+ dev->output_running = 1;
+ wake_up(&dev->prepare_wait_queue);
+ }
+}
+
+static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
+{
+ int i, frame;
+ struct urb **urbs;
+ struct usb_device *usb_dev = dev->chip.dev;
+ unsigned int pipe;
+
+ pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ?
+ usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) :
+ usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE);
+
+ urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL);
+ if (!urbs) {
+ log("unable to kmalloc() urbs, OOM!?\n");
+ *ret = -ENOMEM;
+ return NULL;
+ }
+
+ for (i = 0; i < N_URBS; i++) {
+ urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
+ if (!urbs[i]) {
+ log("unable to usb_alloc_urb(), OOM!?\n");
+ *ret = -ENOMEM;
+ return urbs;
+ }
+
+ urbs[i]->transfer_buffer =
+ kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
+ if (!urbs[i]->transfer_buffer) {
+ log("unable to kmalloc() transfer buffer, OOM!?\n");
+ *ret = -ENOMEM;
+ return urbs;
+ }
+
+ for (frame = 0; frame < FRAMES_PER_URB; frame++) {
+ struct usb_iso_packet_descriptor *iso =
+ &urbs[i]->iso_frame_desc[frame];
+
+ iso->offset = BYTES_PER_FRAME * frame;
+ iso->length = BYTES_PER_FRAME;
+ }
+
+ urbs[i]->dev = usb_dev;
+ urbs[i]->pipe = pipe;
+ urbs[i]->transfer_buffer_length = FRAMES_PER_URB
+ * BYTES_PER_FRAME;
+ urbs[i]->context = &dev->data_cb_info[i];
+ urbs[i]->interval = 1;
+ urbs[i]->transfer_flags = URB_ISO_ASAP;
+ urbs[i]->number_of_packets = FRAMES_PER_URB;
+ urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ?
+ read_completed : write_completed;
+ }
+
+ *ret = 0;
+ return urbs;
+}
+
+static void free_urbs(struct urb **urbs)
+{
+ int i;
+
+ if (!urbs)
+ return;
+
+ for (i = 0; i < N_URBS; i++) {
+ if (!urbs[i])
+ continue;
+
+ usb_kill_urb(urbs[i]);
+ kfree(urbs[i]->transfer_buffer);
+ usb_free_urb(urbs[i]);
+ }
+
+ kfree(urbs);
+}
+
+int __devinit snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
+{
+ int i, ret;
+
+ dev->n_audio_in = max(dev->spec.num_analog_audio_in,
+ dev->spec.num_digital_audio_in) /
+ CHANNELS_PER_STREAM;
+ dev->n_audio_out = max(dev->spec.num_analog_audio_out,
+ dev->spec.num_digital_audio_out) /
+ CHANNELS_PER_STREAM;
+ dev->n_streams = max(dev->n_audio_in, dev->n_audio_out);
+
+ debug("dev->n_audio_in = %d\n", dev->n_audio_in);
+ debug("dev->n_audio_out = %d\n", dev->n_audio_out);
+ debug("dev->n_streams = %d\n", dev->n_streams);
+
+ if (dev->n_streams > MAX_STREAMS) {
+ log("unable to initialize device, too many streams.\n");
+ return -EINVAL;
+ }
+
+ ret = snd_pcm_new(dev->chip.card, dev->product_name, 0,
+ dev->n_audio_out, dev->n_audio_in, &dev->pcm);
+
+ if (ret < 0) {
+ log("snd_pcm_new() returned %d\n", ret);
+ return ret;
+ }
+
+ dev->pcm->private_data = dev;
+ strcpy(dev->pcm->name, dev->product_name);
+
+ memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
+ memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
+
+ memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware,
+ sizeof(snd_usb_caiaq_pcm_hardware));
+
+ /* setup samplerates */
+ dev->samplerates = dev->pcm_info.rates;
+ switch (dev->chip.usb_id) {
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
+ dev->samplerates |= SNDRV_PCM_RATE_88200;
+ dev->samplerates |= SNDRV_PCM_RATE_192000;
+ break;
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
+ dev->samplerates |= SNDRV_PCM_RATE_88200;
+ break;
+ }
+
+ snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_usb_caiaq_ops);
+ snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_usb_caiaq_ops);
+
+ snd_pcm_lib_preallocate_pages_for_all(dev->pcm,
+ SNDRV_DMA_TYPE_CONTINUOUS,
+ snd_dma_continuous_data(GFP_KERNEL),
+ MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
+
+ dev->data_cb_info =
+ kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS,
+ GFP_KERNEL);
+
+ if (!dev->data_cb_info)
+ return -ENOMEM;
+
+ for (i = 0; i < N_URBS; i++) {
+ dev->data_cb_info[i].dev = dev;
+ dev->data_cb_info[i].index = i;
+ }
+
+ dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret);
+ if (ret < 0) {
+ kfree(dev->data_cb_info);
+ free_urbs(dev->data_urbs_in);
+ return ret;
+ }
+
+ dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
+ if (ret < 0) {
+ kfree(dev->data_cb_info);
+ free_urbs(dev->data_urbs_in);
+ free_urbs(dev->data_urbs_out);
+ return ret;
+ }
+
+ return 0;
+}
+
+void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev)
+{
+ debug("snd_usb_caiaq_audio_free (%p)\n", dev);
+ stream_stop(dev);
+ free_urbs(dev->data_urbs_in);
+ free_urbs(dev->data_urbs_out);
+ kfree(dev->data_cb_info);
+}
+
diff --git a/sound/usb/caiaq/caiaq-audio.h b/sound/usb/caiaq/caiaq-audio.h
new file mode 100644
index 00000000000..8ab1f8d9529
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-audio.h
@@ -0,0 +1,7 @@
+#ifndef CAIAQ_AUDIO_H
+#define CAIAQ_AUDIO_H
+
+int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev);
+void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev);
+
+#endif /* CAIAQ_AUDIO_H */
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
new file mode 100644
index 00000000000..4709347326f
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -0,0 +1,436 @@
+/*
+ * caiaq.c: ALSA driver for caiaq/NativeInstruments devices
+ *
+ * Copyright (c) 2007 Daniel Mack <daniel@caiaq.de>
+ * Karsten Wiese <fzu@wemgehoertderstaat.de>
+ *
+ * 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
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+
+#include "caiaq-device.h"
+#include "caiaq-audio.h"
+#include "caiaq-midi.h"
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+#include "caiaq-input.h"
+#endif
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.1.0");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
+ "{Native Instruments, Kore Controller},"
+ "{Native Instruments, Audio Kontrol 1}"
+ "{Native Instruments, Audio 8 DJ}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
+static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+static int snd_card_used[SNDRV_CARDS];
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the caiaq sound device");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for the caiaq soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable the caiaq soundcard.");
+
+enum {
+ SAMPLERATE_44100 = 0,
+ SAMPLERATE_48000 = 1,
+ SAMPLERATE_96000 = 2,
+ SAMPLERATE_192000 = 3,
+ SAMPLERATE_88200 = 4,
+ SAMPLERATE_INVALID = 0xff
+};
+
+enum {
+ DEPTH_NONE = 0,
+ DEPTH_16 = 1,
+ DEPTH_24 = 2,
+ DEPTH_32 = 3
+};
+
+static struct usb_device_id snd_usb_id_table[] = {
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = USB_VID_NATIVEINSTRUMENTS,
+ .idProduct = USB_PID_RIGKONTROL2
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = USB_VID_NATIVEINSTRUMENTS,
+ .idProduct = USB_PID_KORECONTROLLER
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = USB_VID_NATIVEINSTRUMENTS,
+ .idProduct = USB_PID_AK1
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = USB_VID_NATIVEINSTRUMENTS,
+ .idProduct = USB_PID_AUDIO8DJ
+ },
+ { /* terminator */ }
+};
+
+static void usb_ep1_command_reply_dispatch (struct urb* urb)
+{
+ int ret;
+ struct snd_usb_caiaqdev *dev = urb->context;
+ unsigned char *buf = urb->transfer_buffer;
+
+ if (urb->status || !dev) {
+ log("received EP1 urb->status = %i\n", urb->status);
+ return;
+ }
+
+ switch(buf[0]) {
+ case EP1_CMD_GET_DEVICE_INFO:
+ memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec));
+ dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version);
+ debug("device spec (firmware %d): audio: %d in, %d out, "
+ "MIDI: %d in, %d out, data alignment %d\n",
+ dev->spec.fw_version,
+ dev->spec.num_analog_audio_in,
+ dev->spec.num_analog_audio_out,
+ dev->spec.num_midi_in,
+ dev->spec.num_midi_out,
+ dev->spec.data_alignment);
+
+ dev->spec_received++;
+ wake_up(&dev->ep1_wait_queue);
+ break;
+ case EP1_CMD_AUDIO_PARAMS:
+ dev->audio_parm_answer = buf[1];
+ wake_up(&dev->ep1_wait_queue);
+ break;
+ case EP1_CMD_MIDI_READ:
+ snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]);
+ break;
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+ case EP1_CMD_READ_ERP:
+ case EP1_CMD_READ_ANALOG:
+ case EP1_CMD_READ_IO:
+ snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length);
+ break;
+#endif
+ }
+
+ dev->ep1_in_urb.actual_length = 0;
+ ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC);
+ if (ret < 0)
+ log("unable to submit urb. OOM!?\n");
+}
+
+static int send_command (struct snd_usb_caiaqdev *dev,
+ unsigned char command,
+ const unsigned char *buffer,
+ int len)
+{
+ int actual_len;
+ struct usb_device *usb_dev = dev->chip.dev;
+
+ if (!usb_dev)
+ return -EIO;
+
+ if (len > EP1_BUFSIZE - 1)
+ len = EP1_BUFSIZE - 1;
+
+ if (buffer && len > 0)
+ memcpy(dev->ep1_out_buf+1, buffer, len);
+
+ dev->ep1_out_buf[0] = command;
+ return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1),
+ dev->ep1_out_buf, len+1, &actual_len, 200);
+}
+
+int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev,
+ int rate, int depth, int bpp)
+{
+ int ret;
+ char tmp[5];
+
+ switch (rate) {
+ case 44100: tmp[0] = SAMPLERATE_44100; break;
+ case 48000: tmp[0] = SAMPLERATE_48000; break;
+ case 88200: tmp[0] = SAMPLERATE_88200; break;
+ case 96000: tmp[0] = SAMPLERATE_96000; break;
+ case 192000: tmp[0] = SAMPLERATE_192000; break;
+ default: return -EINVAL;
+ }
+
+ switch (depth) {
+ case 16: tmp[1] = DEPTH_16; break;
+ case 24: tmp[1] = DEPTH_24; break;
+ default: return -EINVAL;
+ }
+
+ tmp[2] = bpp & 0xff;
+ tmp[3] = bpp >> 8;
+ tmp[4] = 1; /* packets per microframe */
+
+ debug("setting audio params: %d Hz, %d bits, %d bpp\n",
+ rate, depth, bpp);
+
+ dev->audio_parm_answer = -1;
+ ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp));
+
+ if (ret)
+ return ret;
+
+ if (!wait_event_timeout(dev->ep1_wait_queue,
+ dev->audio_parm_answer >= 0, HZ))
+ return -EPIPE;
+
+ if (dev->audio_parm_answer != 1)
+ debug("unable to set the device's audio params\n");
+
+ return dev->audio_parm_answer == 1 ? 0 : -EINVAL;
+}
+
+int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev,
+ int digital, int analog, int erp)
+{
+ char tmp[3] = { digital, analog, erp };
+ return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp));
+}
+
+static void setup_card(struct snd_usb_caiaqdev *dev)
+{
+ int ret;
+ char val[3];
+
+ /* device-specific startup specials */
+ switch (dev->chip.usb_id) {
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
+ /* RigKontrol2 - display centered dash ('-') */
+ val[0] = 0x00;
+ val[1] = 0x00;
+ val[2] = 0x01;
+ send_command(dev, EP1_CMD_WRITE_IO, val, 3);
+ break;
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
+ /* Audio Kontrol 1 - make USB-LED stop blinking */
+ val[0] = 0x00;
+ send_command(dev, EP1_CMD_WRITE_IO, val, 1);
+ break;
+ }
+
+ ret = snd_usb_caiaq_audio_init(dev);
+ if (ret < 0)
+ log("Unable to set up audio system (ret=%d)\n", ret);
+
+ ret = snd_usb_caiaq_midi_init(dev);
+ if (ret < 0)
+ log("Unable to set up MIDI system (ret=%d)\n", ret);
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+ ret = snd_usb_caiaq_input_init(dev);
+ if (ret < 0)
+ log("Unable to set up input system (ret=%d)\n", ret);
+#endif
+
+ /* finally, register the card and all its sub-instances */
+ ret = snd_card_register(dev->chip.card);
+ if (ret < 0) {
+ log("snd_card_register() returned %d\n", ret);
+ snd_card_free(dev->chip.card);
+ }
+}
+
+static struct snd_card* create_card(struct usb_device* usb_dev)
+{
+ int devnum;
+ struct snd_card *card;
+ struct snd_usb_caiaqdev *dev;
+
+ for (devnum = 0; devnum < SNDRV_CARDS; devnum++)
+ if (enable[devnum] && !snd_card_used[devnum])
+ break;
+
+ if (devnum >= SNDRV_CARDS)
+ return NULL;
+
+ card = snd_card_new(index[devnum], id[devnum], THIS_MODULE,
+ sizeof(struct snd_usb_caiaqdev));
+ if (!card)
+ return NULL;
+
+ dev = caiaqdev(card);
+ dev->chip.dev = usb_dev;
+ dev->chip.card = card;
+ dev->chip.usb_id = USB_ID(usb_dev->descriptor.idVendor,
+ usb_dev->descriptor.idProduct);
+ spin_lock_init(&dev->spinlock);
+ snd_card_set_dev(card, &usb_dev->dev);
+
+ return card;
+}
+
+static int init_card(struct snd_usb_caiaqdev *dev)
+{
+ char *c;
+ struct usb_device *usb_dev = dev->chip.dev;
+ struct snd_card *card = dev->chip.card;
+ int err, len;
+
+ if (usb_set_interface(usb_dev, 0, 1) != 0) {
+ log("can't set alt interface.\n");
+ return -EIO;
+ }
+
+ usb_init_urb(&dev->ep1_in_urb);
+ usb_init_urb(&dev->midi_out_urb);
+
+ usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev,
+ usb_rcvbulkpipe(usb_dev, 0x1),
+ dev->ep1_in_buf, EP1_BUFSIZE,
+ usb_ep1_command_reply_dispatch, dev);
+
+ usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev,
+ usb_sndbulkpipe(usb_dev, 0x1),
+ dev->midi_out_buf, EP1_BUFSIZE,
+ snd_usb_caiaq_midi_output_done, dev);
+
+ init_waitqueue_head(&dev->ep1_wait_queue);
+ init_waitqueue_head(&dev->prepare_wait_queue);
+
+ if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
+ return -EIO;
+
+ err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
+ if (err)
+ return err;
+
+ if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
+ return -ENODEV;
+
+ usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
+ dev->vendor_name, CAIAQ_USB_STR_LEN);
+
+ usb_string(usb_dev, usb_dev->descriptor.iProduct,
+ dev->product_name, CAIAQ_USB_STR_LEN);
+
+ usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
+ dev->serial, CAIAQ_USB_STR_LEN);
+
+ /* terminate serial string at first white space occurence */
+ c = strchr(dev->serial, ' ');
+ if (c)
+ *c = '\0';
+
+ strcpy(card->driver, MODNAME);
+ strcpy(card->shortname, dev->product_name);
+
+ len = snprintf(card->longname, sizeof(card->longname),
+ "%s %s (serial %s, ",
+ dev->vendor_name, dev->product_name, dev->serial);
+
+ if (len < sizeof(card->longname) - 2)
+ len += usb_make_path(usb_dev, card->longname + len,
+ sizeof(card->longname) - len);
+
+ card->longname[len++] = ')';
+ card->longname[len] = '\0';
+ setup_card(dev);
+ return 0;
+}
+
+static int snd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int ret;
+ struct snd_card *card;
+ struct usb_device *device = interface_to_usbdev(intf);
+
+ card = create_card(device);
+
+ if (!card)
+ return -ENOMEM;
+
+ dev_set_drvdata(&intf->dev, card);
+ ret = init_card(caiaqdev(card));
+ if (ret < 0) {
+ log("unable to init card! (ret=%d)\n", ret);
+ snd_card_free(card);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void snd_disconnect(struct usb_interface *intf)
+{
+ struct snd_usb_caiaqdev *dev;
+ struct snd_card *card = dev_get_drvdata(&intf->dev);
+
+ debug("snd_disconnect(%p)\n", intf);
+
+ if (!card)
+ return;
+
+ dev = caiaqdev(card);
+ snd_card_disconnect(card);
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+ snd_usb_caiaq_input_free(dev);
+#endif
+ snd_usb_caiaq_audio_free(dev);
+
+ usb_kill_urb(&dev->ep1_in_urb);
+ usb_kill_urb(&dev->midi_out_urb);
+
+ snd_card_free(card);
+ usb_reset_device(interface_to_usbdev(intf));
+}
+
+
+MODULE_DEVICE_TABLE(usb, snd_usb_id_table);
+static struct usb_driver snd_usb_driver = {
+ .name = MODNAME,
+ .probe = snd_probe,
+ .disconnect = snd_disconnect,
+ .id_table = snd_usb_id_table,
+};
+
+static int __init snd_module_init(void)
+{
+ return usb_register(&snd_usb_driver);
+}
+
+static void __exit snd_module_exit(void)
+{
+ usb_deregister(&snd_usb_driver);
+}
+
+module_init(snd_module_init)
+module_exit(snd_module_exit)
+
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h
new file mode 100644
index 00000000000..088d5ec241f
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-device.h
@@ -0,0 +1,116 @@
+#ifndef CAIAQ_DEVICE_H
+#define CAIAQ_DEVICE_H
+
+#include "../usbaudio.h"
+
+#define USB_VID_NATIVEINSTRUMENTS 0x17cc
+
+#define USB_PID_RIGKONTROL2 0x1969
+#define USB_PID_KORECONTROLLER 0x4711
+#define USB_PID_AK1 0x0815
+#define USB_PID_AUDIO8DJ 0x1978
+
+#define EP1_BUFSIZE 64
+#define CAIAQ_USB_STR_LEN 0xff
+#define MAX_STREAMS 32
+
+//#define SND_USB_CAIAQ_DEBUG
+
+#define MODNAME "snd-usb-caiaq"
+#define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x)
+
+#ifdef SND_USB_CAIAQ_DEBUG
+#define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x)
+#else
+#define debug(x...) do { } while(0)
+#endif
+
+#define EP1_CMD_GET_DEVICE_INFO 0x1
+#define EP1_CMD_READ_ERP 0x2
+#define EP1_CMD_READ_ANALOG 0x3
+#define EP1_CMD_READ_IO 0x4
+#define EP1_CMD_WRITE_IO 0x5
+#define EP1_CMD_MIDI_READ 0x6
+#define EP1_CMD_MIDI_WRITE 0x7
+#define EP1_CMD_AUDIO_PARAMS 0x9
+#define EP1_CMD_AUTO_MSG 0xb
+
+struct caiaq_device_spec {
+ unsigned short fw_version;
+ unsigned char hw_subtype;
+ unsigned char num_erp;
+ unsigned char num_analog_in;
+ unsigned char num_digital_in;
+ unsigned char num_digital_out;
+ unsigned char num_analog_audio_out;
+ unsigned char num_analog_audio_in;
+ unsigned char num_digital_audio_out;
+ unsigned char num_digital_audio_in;
+ unsigned char num_midi_out;
+ unsigned char num_midi_in;
+ unsigned char data_alignment;
+} __attribute__ ((packed));
+
+struct snd_usb_caiaq_cb_info;
+
+struct snd_usb_caiaqdev {
+ struct snd_usb_audio chip;
+
+ struct urb ep1_in_urb;
+ struct urb midi_out_urb;
+ struct urb **data_urbs_in;
+ struct urb **data_urbs_out;
+ struct snd_usb_caiaq_cb_info *data_cb_info;
+
+ unsigned char ep1_in_buf[EP1_BUFSIZE];
+ unsigned char ep1_out_buf[EP1_BUFSIZE];
+ unsigned char midi_out_buf[EP1_BUFSIZE];
+
+ struct caiaq_device_spec spec;
+ spinlock_t spinlock;
+ wait_queue_head_t ep1_wait_queue;
+ wait_queue_head_t prepare_wait_queue;
+ int spec_received, audio_parm_answer;
+
+ char vendor_name[CAIAQ_USB_STR_LEN];
+ char product_name[CAIAQ_USB_STR_LEN];
+ char serial[CAIAQ_USB_STR_LEN];
+
+ int n_streams, n_audio_in, n_audio_out;
+ int streaming, first_packet, output_running;
+ int audio_in_buf_pos[MAX_STREAMS];
+ int audio_out_buf_pos[MAX_STREAMS];
+ int period_in_count[MAX_STREAMS];
+ int period_out_count[MAX_STREAMS];
+ int input_panic, output_panic;
+ char *audio_in_buf, *audio_out_buf;
+ unsigned int samplerates;
+
+ struct snd_pcm_substream *sub_playback[MAX_STREAMS];
+ struct snd_pcm_substream *sub_capture[MAX_STREAMS];
+
+ /* Linux input */
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+ struct input_dev *input_dev;
+#endif
+
+ /* ALSA */
+ struct snd_pcm *pcm;
+ struct snd_pcm_hardware pcm_info;
+ struct snd_rawmidi *rmidi;
+ struct snd_rawmidi_substream *midi_receive_substream;
+ struct snd_rawmidi_substream *midi_out_substream;
+};
+
+struct snd_usb_caiaq_cb_info {
+ struct snd_usb_caiaqdev *dev;
+ int index;
+};
+
+#define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data)
+
+int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp);
+int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp);
+
+
+#endif /* CAIAQ_DEVICE_H */
diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c
new file mode 100644
index 00000000000..3acd12db695
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-input.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz
+ *
+ * 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
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+#include <sound/pcm.h>
+#include "caiaq-device.h"
+#include "caiaq-input.h"
+
+#ifdef CONFIG_SND_USB_CAIAQ_INPUT
+
+static unsigned char keycode_ak1[] = { KEY_C, KEY_B, KEY_A };
+static unsigned char keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4,
+ KEY_5, KEY_6, KEY_7 };
+
+#define DEG90 (range/2)
+#define DEG180 (range)
+#define DEG270 (DEG90 + DEG180)
+#define DEG360 (DEG180 * 2)
+#define HIGH_PEAK (268)
+#define LOW_PEAK (-7)
+
+/* some of these devices have endless rotation potentiometers
+ * built in which use two tapers, 90 degrees phase shifted.
+ * this algorithm decodes them to one single value, ranging
+ * from 0 to 999 */
+static unsigned int decode_erp(unsigned char a, unsigned char b)
+{
+ int weight_a, weight_b;
+ int pos_a, pos_b;
+ int ret;
+ int range = HIGH_PEAK - LOW_PEAK;
+ int mid_value = (HIGH_PEAK + LOW_PEAK) / 2;
+
+ weight_b = abs(mid_value-a) - (range/2 - 100)/2;
+
+ if (weight_b < 0)
+ weight_b = 0;
+
+ if (weight_b > 100)
+ weight_b = 100;
+
+ weight_a = 100 - weight_b;
+
+ if (a < mid_value) {
+ /* 0..90 and 270..360 degrees */
+ pos_b = b - LOW_PEAK + DEG270;
+ if (pos_b >= DEG360)
+ pos_b -= DEG360;
+ } else
+ /* 90..270 degrees */
+ pos_b = HIGH_PEAK - b + DEG90;
+
+
+ if (b > mid_value)
+ /* 0..180 degrees */
+ pos_a = a - LOW_PEAK;
+ else
+ /* 180..360 degrees */
+ pos_a = HIGH_PEAK - a + DEG180;
+
+ /* interpolate both slider values, depending on weight factors */
+ /* 0..99 x DEG360 */
+ ret = pos_a * weight_a + pos_b * weight_b;
+
+ /* normalize to 0..999 */
+ ret *= 10;
+ ret /= DEG360;
+
+ if (ret < 0)
+ ret += 1000;
+
+ if (ret >= 1000)
+ ret -= 1000;
+
+ return ret;
+}
+
+#undef DEG90
+#undef DEG180
+#undef DEG270
+#undef DEG360
+#undef HIGH_PEAK
+#undef LOW_PEAK
+
+
+static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
+ const char *buf, unsigned int len)
+{
+ switch(dev->input_dev->id.product) {
+ case USB_PID_RIGKONTROL2:
+ input_report_abs(dev->input_dev, ABS_X, (buf[4] << 8) |buf[5]);
+ input_report_abs(dev->input_dev, ABS_Y, (buf[0] << 8) |buf[1]);
+ input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]);
+ input_sync(dev->input_dev);
+ break;
+ }
+}
+
+static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
+ const char *buf, unsigned int len)
+{
+ int i;
+
+ switch(dev->input_dev->id.product) {
+ case USB_PID_AK1:
+ i = decode_erp(buf[0], buf[1]);
+ input_report_abs(dev->input_dev, ABS_X, i);
+ input_sync(dev->input_dev);
+ break;
+ }
+}
+
+static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
+ char *buf, unsigned int len)
+{
+ int i;
+ unsigned char *keycode = dev->input_dev->keycode;
+
+ if (!keycode)
+ return;
+
+ if (dev->input_dev->id.product == USB_PID_RIGKONTROL2)
+ for (i=0; i<len; i++)
+ buf[i] = ~buf[i];
+
+ for (i=0; (i<dev->input_dev->keycodemax) && (i < len); i++)
+ input_report_key(dev->input_dev, keycode[i],
+ buf[i/8] & (1 << (i%8)));
+
+ input_sync(dev->input_dev);
+}
+
+void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
+ char *buf,
+ unsigned int len)
+{
+ if (!dev->input_dev || (len < 1))
+ return;
+
+ switch (buf[0]) {
+ case EP1_CMD_READ_ANALOG:
+ snd_caiaq_input_read_analog(dev, buf+1, len-1);
+ break;
+ case EP1_CMD_READ_ERP:
+ snd_caiaq_input_read_erp(dev, buf+1, len-1);
+ break;
+ case EP1_CMD_READ_IO:
+ snd_caiaq_input_read_io(dev, buf+1, len-1);
+ break;
+ }
+}
+
+int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
+{
+ struct usb_device *usb_dev = dev->chip.dev;
+ struct input_dev *input;
+ int i, ret;
+
+ input = input_allocate_device();
+ if (!input)
+ return -ENOMEM;
+
+ input->name = dev->product_name;
+ input->id.bustype = BUS_USB;
+ input->id.vendor = usb_dev->descriptor.idVendor;
+ input->id.product = usb_dev->descriptor.idProduct;
+ input->id.version = usb_dev->descriptor.bcdDevice;
+
+ switch (dev->chip.usb_id) {
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
+ input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
+ input->keycode = keycode_rk2;
+ input->keycodesize = sizeof(char);
+ input->keycodemax = ARRAY_SIZE(keycode_rk2);
+ for (i=0; i<ARRAY_SIZE(keycode_rk2); i++)
+ set_bit(keycode_rk2[i], input->keybit);
+
+ input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
+ input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
+ input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
+ snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
+ break;
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
+ input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input->absbit[0] = BIT(ABS_X);
+ input->keycode = keycode_ak1;
+ input->keycodesize = sizeof(char);
+ input->keycodemax = ARRAY_SIZE(keycode_ak1);
+ for (i=0; i<ARRAY_SIZE(keycode_ak1); i++)
+ set_bit(keycode_ak1[i], input->keybit);
+
+ input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
+ snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5);
+ break;
+ default:
+ /* no input methods supported on this device */
+ input_free_device(input);
+ return 0;
+ }
+
+ ret = input_register_device(input);
+ if (ret < 0) {
+ input_free_device(input);
+ return ret;
+ }
+
+ dev->input_dev = input;
+ return 0;
+}
+
+void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
+{
+ if (!dev || !dev->input_dev)
+ return;
+
+ input_unregister_device(dev->input_dev);
+ input_free_device(dev->input_dev);
+ dev->input_dev = NULL;
+}
+
+#endif /* CONFIG_SND_USB_CAIAQ_INPUT */
+
diff --git a/sound/usb/caiaq/caiaq-input.h b/sound/usb/caiaq/caiaq-input.h
new file mode 100644
index 00000000000..ced53557786
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-input.h
@@ -0,0 +1,8 @@
+#ifndef CAIAQ_INPUT_H
+#define CAIAQ_INPUT_H
+
+void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len);
+int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev);
+void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev);
+
+#endif
diff --git a/sound/usb/caiaq/caiaq-midi.c b/sound/usb/caiaq/caiaq-midi.c
new file mode 100644
index 00000000000..793ca20ce34
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-midi.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2006,2007 Daniel Mack
+ *
+ * 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
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+#include <sound/pcm.h>
+
+#include "caiaq-device.h"
+#include "caiaq-midi.h"
+
+
+static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
+{
+ struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
+
+ if (!dev)
+ return;
+
+ dev->midi_receive_substream = up ? substream : NULL;
+}
+
+
+static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
+ struct snd_rawmidi_substream *substream)
+{
+ int len, ret;
+
+ dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
+ dev->midi_out_buf[1] = 0; /* port */
+ len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3);
+
+ if (len <= 0)
+ return;
+
+ dev->midi_out_buf[2] = len;
+ dev->midi_out_urb.transfer_buffer_length = len+3;
+
+ ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
+ if (ret < 0)
+ log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n",
+ substream, ret);
+}
+
+static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
+{
+ struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
+
+ if (dev->midi_out_substream != NULL)
+ return;
+
+ if (!up) {
+ dev->midi_out_substream = NULL;
+ return;
+ }
+
+ dev->midi_out_substream = substream;
+ snd_usb_caiaq_midi_send(dev, substream);
+}
+
+
+static struct snd_rawmidi_ops snd_usb_caiaq_midi_output =
+{
+ .open = snd_usb_caiaq_midi_output_open,
+ .close = snd_usb_caiaq_midi_output_close,
+ .trigger = snd_usb_caiaq_midi_output_trigger,
+};
+
+static struct snd_rawmidi_ops snd_usb_caiaq_midi_input =
+{
+ .open = snd_usb_caiaq_midi_input_open,
+ .close = snd_usb_caiaq_midi_input_close,
+ .trigger = snd_usb_caiaq_midi_input_trigger,
+};
+
+void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev,
+ int port, const char *buf, int len)
+{
+ if (!dev->midi_receive_substream)
+ return;
+
+ snd_rawmidi_receive(dev->midi_receive_substream, buf, len);
+}
+
+int __devinit snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
+{
+ int ret;
+ struct snd_rawmidi *rmidi;
+
+ ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,
+ device->spec.num_midi_out,
+ device->spec.num_midi_in,
+ &rmidi);
+
+ if (ret < 0)
+ return ret;
+
+ strcpy(rmidi->name, device->product_name);
+
+ rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
+ rmidi->private_data = device;
+
+ if (device->spec.num_midi_out > 0) {
+ rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+ &snd_usb_caiaq_midi_output);
+ }
+
+ if (device->spec.num_midi_in > 0) {
+ rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+ &snd_usb_caiaq_midi_input);
+ }
+
+ device->rmidi = rmidi;
+
+ return 0;
+}
+
+void snd_usb_caiaq_midi_output_done(struct urb* urb)
+{
+ struct snd_usb_caiaqdev *dev = urb->context;
+ char *buf = urb->transfer_buffer;
+
+ if (urb->status != 0)
+ return;
+
+ if (!dev->midi_out_substream)
+ return;
+
+ snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]);
+ dev->midi_out_substream = NULL;
+ snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
+}
+
diff --git a/sound/usb/caiaq/caiaq-midi.h b/sound/usb/caiaq/caiaq-midi.h
new file mode 100644
index 00000000000..9d16db027fc
--- /dev/null
+++ b/sound/usb/caiaq/caiaq-midi.h
@@ -0,0 +1,8 @@
+#ifndef CAIAQ_MIDI_H
+#define CAIAQ_MIDI_H
+
+int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
+void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
+void snd_usb_caiaq_midi_output_done(struct urb* urb);
+
+#endif /* CAIAQ_MIDI_H */
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index b6d886373bb..8ebc1adb5ed 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1878,6 +1878,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
}
/* set the period time minimum 1ms */
+ /* FIXME: high-speed mode allows 125us minimum period, but many parts
+ * in the current code assume the 1ms period.
+ */
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1000 * MIN_PACKS_URB,
/*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX);
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 24f5a26c5f0..99295f9b769 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -1,7 +1,7 @@
/*
* usbmidi.c - ALSA USB MIDI driver
*
- * Copyright (c) 2002-2005 Clemens Ladisch
+ * Copyright (c) 2002-2007 Clemens Ladisch
* All rights reserved.
*
* Based on the OSS usb-midi driver by NAGANO Daisuke,
@@ -145,6 +145,7 @@ struct snd_usb_midi_in_endpoint {
struct urb* urb;
struct usbmidi_in_port {
struct snd_rawmidi_substream *substream;
+ u8 running_status_length;
} ports[0x10];
u8 seen_f5;
u8 error_resubmit;
@@ -366,6 +367,46 @@ static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep,
}
/*
+ * Buggy M-Audio device: running status on input results in a packet that has
+ * the data bytes but not the status byte and that is marked with CIN 4.
+ */
+static void snd_usbmidi_maudio_broken_running_status_input(
+ struct snd_usb_midi_in_endpoint* ep,
+ uint8_t* buffer, int buffer_length)
+{
+ int i;
+
+ for (i = 0; i + 3 < buffer_length; i += 4)
+ if (buffer[i] != 0) {
+ int cable = buffer[i] >> 4;
+ u8 cin = buffer[i] & 0x0f;
+ struct usbmidi_in_port *port = &ep->ports[cable];
+ int length;
+
+ length = snd_usbmidi_cin_length[cin];
+ if (cin == 0xf && buffer[i + 1] >= 0xf8)
+ ; /* realtime msg: no running status change */
+ else if (cin >= 0x8 && cin <= 0xe)
+ /* channel msg */
+ port->running_status_length = length - 1;
+ else if (cin == 0x4 &&
+ port->running_status_length != 0 &&
+ buffer[i + 1] < 0x80)
+ /* CIN 4 that is not a SysEx */
+ length = port->running_status_length;
+ else
+ /*
+ * All other msgs cannot begin running status.
+ * (A channel msg sent as two or three CIN 0xF
+ * packets could in theory, but this device
+ * doesn't use this format.)
+ */
+ port->running_status_length = 0;
+ snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length);
+ }
+}
+
+/*
* Adds one USB MIDI packet to the output buffer.
*/
static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0,
@@ -525,6 +566,12 @@ static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
.output_packet = snd_usbmidi_output_midiman_packet,
};
+static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
+ .input = snd_usbmidi_maudio_broken_running_status_input,
+ .output = snd_usbmidi_standard_output,
+ .output_packet = snd_usbmidi_output_standard_packet,
+};
+
/*
* Novation USB MIDI protocol: number of data bytes is in the first byte
* (when receiving) (+1!) or in the second byte (when sending); data begins
@@ -918,7 +965,11 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
}
/* we never use interrupt output pipes */
pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
- ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1);
+ if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */
+ /* FIXME: we need more URBs to get reasonable bandwidth here: */
+ ep->max_transfer = 4;
+ else
+ ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1);
buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer,
GFP_KERNEL, &ep->urb->transfer_dma);
if (!buffer) {
@@ -1606,6 +1657,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
case QUIRK_MIDI_STANDARD_INTERFACE:
err = snd_usbmidi_get_ms_info(umidi, endpoints);
+ if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */
+ umidi->usb_protocol_ops =
+ &snd_usbmidi_maudio_broken_running_status_ops;
break;
case QUIRK_MIDI_FIXED_ENDPOINT:
memcpy(&endpoints[0], quirk->data,
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 858262068f4..8fcbe93b258 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -40,6 +40,29 @@
.bInterfaceClass = USB_CLASS_VENDOR_SPEC
/*
+ * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
+ * class matches do not take effect without an explicit ID match.
+ */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+ USB_DEVICE_ID_MATCH_INT_CLASS |
+ USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+ .idVendor = 0x046d,
+ .idProduct = 0x08f0,
+ .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 = 0x08f6,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+ .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
+},
+
+/*
* Yamaha devices
*/