From 35dd585aef7da3dba5a71fc9040b0efb26b3c638 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 19 Apr 2008 15:12:23 +0100 Subject: [PATCH] --- yaml --- r: 100801 b: refs/heads/master c: 36149f02cb830570ca57228c8ad3d82742485eb7 h: refs/heads/master i: 100799: 023f1d77db396423011053f67b3545391cdf08c8 v: v3 --- [refs] | 2 +- trunk/.gitignore | 12 +- trunk/Documentation/DocBook/kgdb.tmpl | 20 +- .../feature-removal-schedule.txt | 9 - trunk/Documentation/hwmon/sysfs-interface | 33 +- trunk/Documentation/i2c/writing-clients | 18 +- trunk/Documentation/networking/ip-sysctl.txt | 12 +- trunk/Documentation/networking/s2io.txt | 6 +- .../Documentation/video4linux/CARDLIST.au0828 | 2 +- trunk/MAINTAINERS | 14 +- trunk/Makefile | 2 +- trunk/arch/alpha/Makefile | 1 - trunk/arch/alpha/kernel/core_t2.c | 2 - trunk/arch/alpha/kernel/pci.c | 17 - trunk/arch/alpha/kernel/traps.c | 3 +- trunk/arch/arm/common/dmabounce.c | 3 +- trunk/arch/arm/mach-omap1/Makefile | 4 +- trunk/arch/arm/mach-omap1/board-osk.c | 18 +- trunk/arch/arm/mach-omap1/fpga.c | 10 +- trunk/arch/arm/mach-omap1/mcbsp.c | 280 --- trunk/arch/arm/mach-omap2/Makefile | 8 +- trunk/arch/arm/mach-omap2/clock.c | 201 +- trunk/arch/arm/mach-omap2/clock.h | 6 - trunk/arch/arm/mach-omap2/clock24xx.c | 12 +- trunk/arch/arm/mach-omap2/clock24xx.h | 47 +- trunk/arch/arm/mach-omap2/clock34xx.c | 299 +-- trunk/arch/arm/mach-omap2/clock34xx.h | 147 +- trunk/arch/arm/mach-omap2/cm-regbits-34xx.h | 18 +- trunk/arch/arm/mach-omap2/cm.h | 15 +- trunk/arch/arm/mach-omap2/control.c | 24 +- trunk/arch/arm/mach-omap2/gpmc.c | 2 +- trunk/arch/arm/mach-omap2/id.c | 195 +- trunk/arch/arm/mach-omap2/mcbsp.c | 208 -- trunk/arch/arm/mach-omap2/memory.c | 11 +- trunk/arch/arm/mach-omap2/mux.c | 2 +- trunk/arch/arm/mach-omap2/prcm-common.h | 1 - trunk/arch/arm/mach-omap2/prcm.c | 98 +- trunk/arch/arm/mach-omap2/prm.h | 30 +- trunk/arch/arm/mach-omap2/sdrc.h | 10 +- .../arm/mach-omap2/{sram242x.S => sram-fn.S} | 105 +- trunk/arch/arm/mach-omap2/sram243x.S | 321 --- trunk/arch/arm/mach-omap2/timer-gp.c | 9 +- trunk/arch/arm/mach-realview/platsmp.c | 2 - trunk/arch/arm/plat-omap/Makefile | 2 +- trunk/arch/arm/plat-omap/clock.c | 128 +- trunk/arch/arm/plat-omap/common.c | 59 +- trunk/arch/arm/plat-omap/devices.c | 48 - trunk/arch/arm/plat-omap/dma.c | 766 +++---- trunk/arch/arm/plat-omap/dmtimer.c | 212 +- trunk/arch/arm/plat-omap/mcbsp.c | 767 ++++--- .../sram.S => plat-omap/sram-fn.S} | 6 +- trunk/arch/arm/plat-omap/sram.c | 211 +- trunk/arch/arm/plat-omap/usb.c | 131 +- .../blackfin/kernel/cplb-nompu/cplbinit.c | 6 +- trunk/arch/blackfin/kernel/irqchip.c | 5 - trunk/arch/ia64/kernel/iosapic.c | 2 + trunk/arch/ia64/kernel/setup.c | 6 +- trunk/arch/ia64/kernel/time.c | 1 - trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c | 2 - trunk/arch/powerpc/boot/Makefile | 3 +- trunk/arch/powerpc/kernel/legacy_serial.c | 5 - .../arch/powerpc/platforms/52xx/lite5200_pm.c | 14 +- trunk/arch/x86/Kconfig | 9 +- trunk/arch/x86/kernel/Makefile | 1 - trunk/arch/x86/kernel/i387.c | 4 +- trunk/arch/x86/kernel/kvmclock.c | 89 +- trunk/arch/x86/kernel/pvclock.c | 141 -- trunk/arch/x86/kernel/smpboot.c | 1 + trunk/arch/x86/kvm/i8254.c | 9 +- trunk/arch/x86/kvm/lapic.c | 1 - trunk/arch/x86/kvm/mmu.c | 19 +- trunk/arch/x86/kvm/vmx.c | 19 +- trunk/arch/x86/kvm/x86.c | 91 +- trunk/arch/x86/mm/init_64.c | 8 +- trunk/arch/x86/xen/Kconfig | 3 +- trunk/arch/x86/xen/enlighten.c | 56 +- trunk/arch/x86/xen/mmu.c | 75 +- trunk/arch/x86/xen/mmu.h | 24 +- trunk/arch/x86/xen/time.c | 132 +- trunk/arch/x86/xen/xen-head.S | 6 +- trunk/block/as-iosched.c | 2 - trunk/drivers/acpi/bay.c | 3 - trunk/drivers/acpi/dock.c | 3 - trunk/drivers/acpi/glue.c | 3 - trunk/drivers/char/drm/i915_drv.c | 1 - trunk/drivers/char/drm/i915_irq.c | 4 +- trunk/drivers/char/tty_io.c | 2 +- trunk/drivers/char/tty_ioctl.c | 7 + trunk/drivers/connector/connector.c | 40 - trunk/drivers/firewire/fw-sbp2.c | 3 +- trunk/drivers/hwmon/abituguru3.c | 18 +- trunk/drivers/hwmon/adt7473.c | 3 - trunk/drivers/hwmon/lm75.c | 20 +- trunk/drivers/hwmon/lm85.c | 25 +- trunk/drivers/i2c/busses/i2c-s3c2410.c | 28 +- trunk/drivers/i2c/chips/isp1301_omap.c | 163 +- trunk/drivers/ide/Kconfig | 7 - trunk/drivers/ide/arm/Makefile | 1 - trunk/drivers/ide/arm/bast-ide.c | 90 - trunk/drivers/ide/ide-proc.c | 2 +- .../infiniband/hw/mthca/mthca_memfree.c | 6 +- trunk/drivers/input/ff-core.c | 18 +- trunk/drivers/lguest/x86/core.c | 15 +- trunk/drivers/md/dm-crypt.c | 1 - trunk/drivers/md/md.c | 6 +- trunk/drivers/md/raid10.c | 2 - trunk/drivers/md/raid5.c | 7 +- trunk/drivers/media/common/ir-keymaps.c | 38 - .../media/common/tuners/tda18271-common.c | 10 +- .../drivers/media/common/tuners/tda18271-fe.c | 53 +- trunk/drivers/media/common/tuners/xc5000.c | 30 +- .../drivers/media/common/tuners/xc5000_priv.h | 1 + trunk/drivers/media/dvb/dvb-usb/gl861.c | 27 +- trunk/drivers/media/dvb/dvb-usb/umt-010.c | 2 +- trunk/drivers/media/dvb/frontends/au8522.c | 29 +- trunk/drivers/media/dvb/frontends/stv0299.c | 15 +- trunk/drivers/media/dvb/frontends/tda10023.c | 20 +- trunk/drivers/media/dvb/frontends/tda1004x.c | 29 +- trunk/drivers/media/dvb/ttpci/Kconfig | 1 - trunk/drivers/media/dvb/ttpci/av7110_hw.c | 5 +- trunk/drivers/media/video/Kconfig | 8 - trunk/drivers/media/video/Makefile | 2 - .../drivers/media/video/au0828/au0828-cards.c | 18 - trunk/drivers/media/video/cx18/Kconfig | 4 +- trunk/drivers/media/video/cx18/cx18-av-core.c | 73 +- trunk/drivers/media/video/cx18/cx18-av-core.h | 16 +- trunk/drivers/media/video/cx18/cx18-cards.c | 84 +- trunk/drivers/media/video/cx18/cx18-cards.h | 50 +- trunk/drivers/media/video/cx18/cx18-dvb.c | 17 +- trunk/drivers/media/video/cx18/cx18-gpio.c | 26 +- trunk/drivers/media/video/cx18/cx18-gpio.h | 1 - trunk/drivers/media/video/cx18/cx18-i2c.c | 2 - .../media/video/cx25840/cx25840-core.c | 2 +- trunk/drivers/media/video/cx88/cx88-alsa.c | 6 - .../drivers/media/video/em28xx/em28xx-audio.c | 18 - .../drivers/media/video/em28xx/em28xx-cards.c | 4 - trunk/drivers/media/video/em28xx/em28xx-dvb.c | 10 - trunk/drivers/media/video/em28xx/em28xx-reg.h | 1 - .../drivers/media/video/em28xx/em28xx-video.c | 24 +- trunk/drivers/media/video/pxa_camera.c | 4 +- .../media/video/saa7134/saa7134-alsa.c | 8 +- .../media/video/saa7134/saa7134-cards.c | 56 +- .../drivers/media/video/saa7134/saa7134-dvb.c | 43 +- .../media/video/saa7134/saa7134-empress.c | 37 +- .../media/video/saa7134/saa7134-input.c | 9 - trunk/drivers/media/video/soc_camera.c | 16 + trunk/drivers/media/video/uvc/Makefile | 3 - trunk/drivers/media/video/uvc/uvc_ctrl.c | 1256 ----------- trunk/drivers/media/video/uvc/uvc_driver.c | 1955 ----------------- trunk/drivers/media/video/uvc/uvc_isight.c | 134 -- trunk/drivers/media/video/uvc/uvc_queue.c | 477 ---- trunk/drivers/media/video/uvc/uvc_status.c | 207 -- trunk/drivers/media/video/uvc/uvc_v4l2.c | 1105 ---------- trunk/drivers/media/video/uvc/uvc_video.c | 934 -------- trunk/drivers/media/video/uvc/uvcvideo.h | 796 ------- trunk/drivers/media/video/videodev.c | 245 ++- trunk/drivers/media/video/vivi.c | 7 +- trunk/drivers/mtd/maps/omap_nor.c | 23 +- trunk/drivers/net/3c59x.c | 5 +- trunk/drivers/net/arm/etherh.c | 2 +- trunk/drivers/net/e100.c | 2 - trunk/drivers/net/e1000/e1000_ethtool.c | 2 +- trunk/drivers/net/e1000e/netdev.c | 3 +- trunk/drivers/net/hamradio/dmascc.c | 2 + trunk/drivers/net/igb/igb_main.c | 3 +- trunk/drivers/net/ipg.c | 16 +- trunk/drivers/net/ixgbe/ixgbe_main.c | 3 +- trunk/drivers/net/netxen/netxen_nic_main.c | 18 +- trunk/drivers/net/pcmcia/axnet_cs.c | 2 - trunk/drivers/net/pcmcia/pcnet_cs.c | 3 - trunk/drivers/net/pppoe.c | 2 +- trunk/drivers/net/qla3xxx.c | 2 - trunk/drivers/net/r6040.c | 2 +- trunk/drivers/net/s2io.c | 35 +- trunk/drivers/net/s2io.h | 4 + trunk/drivers/net/tc35815.c | 4 +- trunk/drivers/net/wan/x25_asy.c | 3 - trunk/drivers/net/wireless/b43/leds.c | 3 - trunk/drivers/net/wireless/b43/main.c | 12 +- trunk/drivers/net/wireless/b43legacy/dma.c | 2 +- trunk/drivers/net/wireless/b43legacy/main.c | 6 +- .../net/wireless/hostap/hostap_80211_rx.c | 8 +- trunk/drivers/net/wireless/hostap/hostap_ap.c | 2 +- trunk/drivers/net/wireless/hostap/hostap_cs.c | 8 +- trunk/drivers/net/wireless/hostap/hostap_hw.c | 10 +- .../drivers/net/wireless/hostap/hostap_main.c | 5 +- .../net/wireless/iwlwifi/iwl3945-base.c | 33 +- .../net/wireless/iwlwifi/iwl4965-base.c | 39 +- .../drivers/net/wireless/prism54/islpci_eth.c | 2 +- trunk/drivers/net/wireless/rt2x00/rt2500usb.c | 36 +- trunk/drivers/net/wireless/rt2x00/rt2x00.h | 1 - trunk/drivers/net/wireless/rt2x00/rt2x00dev.c | 38 +- trunk/drivers/net/wireless/rt2x00/rt2x00mac.c | 4 +- trunk/drivers/net/wireless/rt2x00/rt73usb.c | 36 +- trunk/drivers/pci/access.c | 14 +- trunk/drivers/pci/hotplug/acpiphp_glue.c | 17 +- trunk/drivers/pci/pci-sysfs.c | 4 +- trunk/drivers/pci/pci.h | 2 +- trunk/drivers/pci/quirks.c | 42 - trunk/drivers/pcmcia/omap_cf.c | 25 +- trunk/drivers/rtc/rtc-sa1100.c | 4 +- trunk/drivers/scsi/esp_scsi.c | 22 +- trunk/drivers/scsi/ses.c | 2 +- trunk/drivers/thermal/Kconfig | 9 - trunk/drivers/thermal/thermal_sys.c | 4 +- trunk/drivers/usb/gadget/omap_udc.c | 510 ++--- trunk/drivers/usb/gadget/omap_udc.h | 61 +- trunk/drivers/usb/host/ohci-omap.c | 5 +- trunk/drivers/video/pxafb.c | 52 +- trunk/drivers/watchdog/Makefile | 1 + trunk/drivers/xen/events.c | 2 +- trunk/fs/block_dev.c | 10 +- trunk/fs/buffer.c | 13 +- trunk/fs/dcache.c | 68 +- trunk/fs/ext4/resize.c | 3 +- trunk/fs/gfs2/bmap.c | 23 +- trunk/fs/gfs2/rgrp.c | 2 +- trunk/fs/locks.c | 6 + trunk/fs/namei.c | 26 +- trunk/fs/nfs/mount_clnt.c | 5 +- trunk/fs/nfs/super.c | 76 +- trunk/fs/nfs/write.c | 7 +- trunk/fs/pipe.c | 10 +- trunk/fs/select.c | 2 +- trunk/fs/udf/super.c | 57 +- trunk/fs/utimes.c | 59 +- trunk/include/asm-alpha/core_mcpcia.h | 2 +- trunk/include/asm-alpha/core_t2.h | 14 +- trunk/include/asm-alpha/io.h | 6 +- trunk/include/asm-alpha/mmu_context.h | 6 +- trunk/include/asm-alpha/percpu.h | 74 +- trunk/include/asm-alpha/system.h | 10 +- trunk/include/asm-alpha/vga.h | 6 +- .../include/asm-arm/arch-omap/board-2430sdp.h | 5 + trunk/include/asm-arm/arch-omap/board-h3.h | 6 + .../asm-arm/arch-omap/board-innovator.h | 3 + .../asm-arm/arch-omap/board-perseus2.h | 6 + trunk/include/asm-arm/arch-omap/clock.h | 17 +- trunk/include/asm-arm/arch-omap/common.h | 15 - trunk/include/asm-arm/arch-omap/control.h | 4 +- trunk/include/asm-arm/arch-omap/cpu.h | 39 +- trunk/include/asm-arm/arch-omap/dma.h | 378 ++-- trunk/include/asm-arm/arch-omap/dmtimer.h | 1 - trunk/include/asm-arm/arch-omap/fpga.h | 49 +- trunk/include/asm-arm/arch-omap/hardware.h | 1 - trunk/include/asm-arm/arch-omap/io.h | 26 +- trunk/include/asm-arm/arch-omap/irqs.h | 44 +- trunk/include/asm-arm/arch-omap/mcbsp.h | 62 +- trunk/include/asm-arm/arch-omap/omap34xx.h | 72 - trunk/include/asm-arm/arch-omap/sram.h | 37 +- trunk/include/asm-arm/arch-omap/tc.h | 10 +- trunk/include/asm-arm/arch-omap/usb.h | 23 +- trunk/include/asm-generic/Kbuild.asm | 2 +- trunk/include/asm-powerpc/Kbuild | 1 + trunk/include/asm-x86/kvm_host.h | 4 +- trunk/include/asm-x86/kvm_para.h | 18 + trunk/include/asm-x86/msr.h | 2 +- trunk/include/asm-x86/pvclock-abi.h | 42 - trunk/include/asm-x86/pvclock.h | 13 - trunk/include/asm-x86/xen/page.h | 4 + trunk/include/linux/Kbuild | 2 +- trunk/include/linux/audit.h | 2 +- trunk/include/linux/bootmem.h | 2 +- trunk/include/linux/dcache.h | 2 +- trunk/include/linux/fs.h | 3 +- trunk/include/linux/i2c.h | 2 +- trunk/include/linux/inet_lro.h | 6 +- trunk/include/linux/input.h | 2 +- trunk/include/linux/kvm_host.h | 1 - trunk/include/linux/netdevice.h | 4 - trunk/include/linux/thermal.h | 6 +- trunk/include/linux/tty_driver.h | 5 +- trunk/include/media/cx25840.h | 6 +- trunk/include/media/ir-common.h | 1 - trunk/include/media/v4l2-dev.h | 4 +- trunk/include/net/ipv6.h | 6 - trunk/include/net/mac80211.h | 9 - trunk/include/net/net_namespace.h | 11 - trunk/include/net/sch_generic.h | 2 +- trunk/include/xen/interface/xen.h | 7 +- trunk/kernel/audit.c | 6 +- trunk/kernel/auditfilter.c | 3 +- trunk/kernel/futex.c | 93 +- trunk/kernel/kgdb.c | 3 +- trunk/kernel/rcuclassic.c | 16 +- trunk/kernel/sched.c | 18 +- trunk/kernel/sched_rt.c | 3 +- trunk/lib/debugobjects.c | 15 +- trunk/lib/ts_bm.c | 2 +- trunk/mm/bootmem.c | 6 +- trunk/mm/memory.c | 50 +- trunk/mm/slab.c | 5 +- trunk/net/core/dev.c | 10 +- trunk/net/core/fib_rules.c | 4 +- trunk/net/core/filter.c | 1 + trunk/net/core/net_namespace.c | 3 - trunk/net/core/skbuff.c | 17 +- trunk/net/ipv4/inet_fragment.c | 16 +- trunk/net/ipv4/inet_lro.c | 3 +- trunk/net/ipv4/ip_fragment.c | 2 - trunk/net/ipv4/tcp.c | 9 +- trunk/net/ipv4/tcp_ipv4.c | 6 +- trunk/net/ipv6/ip6_input.c | 9 - trunk/net/ipv6/ipv6_sockglue.c | 11 +- trunk/net/ipv6/netfilter/ip6table_mangle.c | 2 +- trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 3 +- trunk/net/ipv6/reassembly.c | 2 - trunk/net/ipv6/route.c | 6 +- trunk/net/ipv6/tcp_ipv6.c | 6 +- trunk/net/mac80211/key.c | 9 - trunk/net/mac80211/tx.c | 9 +- trunk/net/mac80211/wext.c | 7 - trunk/net/mac80211/wme.c | 3 +- trunk/net/netfilter/nf_conntrack_proto_tcp.c | 13 +- trunk/net/netlabel/netlabel_unlabeled.c | 2 +- trunk/net/netlink/af_netlink.c | 2 +- trunk/net/netlink/attr.c | 7 +- trunk/net/sched/Kconfig | 11 + trunk/net/sched/sch_api.c | 6 +- trunk/net/sched/sch_atm.c | 7 +- trunk/net/sched/sch_cbq.c | 8 +- trunk/net/sched/sch_dsmark.c | 2 +- trunk/net/sched/sch_generic.c | 2 +- trunk/net/sched/sch_hfsc.c | 6 +- trunk/net/sched/sch_htb.c | 4 +- trunk/net/sched/sch_ingress.c | 2 +- trunk/net/sched/sch_prio.c | 2 +- trunk/net/sched/sch_sfq.c | 2 +- trunk/net/sctp/socket.c | 4 +- trunk/net/unix/af_unix.c | 52 +- trunk/net/wireless/reg.c | 18 - trunk/sound/isa/sb/sb_mixer.c | 4 +- trunk/sound/pci/aw2/aw2-alsa.c | 4 +- trunk/virt/kvm/ioapic.c | 31 +- 334 files changed, 3303 insertions(+), 13552 deletions(-) delete mode 100644 trunk/arch/arm/mach-omap1/mcbsp.c delete mode 100644 trunk/arch/arm/mach-omap2/mcbsp.c rename trunk/arch/arm/mach-omap2/{sram242x.S => sram-fn.S} (80%) delete mode 100644 trunk/arch/arm/mach-omap2/sram243x.S rename trunk/arch/arm/{mach-omap1/sram.S => plat-omap/sram-fn.S} (92%) delete mode 100644 trunk/arch/x86/kernel/pvclock.c delete mode 100644 trunk/drivers/ide/arm/bast-ide.c delete mode 100644 trunk/drivers/media/video/uvc/Makefile delete mode 100644 trunk/drivers/media/video/uvc/uvc_ctrl.c delete mode 100644 trunk/drivers/media/video/uvc/uvc_driver.c delete mode 100644 trunk/drivers/media/video/uvc/uvc_isight.c delete mode 100644 trunk/drivers/media/video/uvc/uvc_queue.c delete mode 100644 trunk/drivers/media/video/uvc/uvc_status.c delete mode 100644 trunk/drivers/media/video/uvc/uvc_v4l2.c delete mode 100644 trunk/drivers/media/video/uvc/uvc_video.c delete mode 100644 trunk/drivers/media/video/uvc/uvcvideo.h delete mode 100644 trunk/include/asm-arm/arch-omap/omap34xx.h delete mode 100644 trunk/include/asm-x86/pvclock-abi.h delete mode 100644 trunk/include/asm-x86/pvclock.h diff --git a/[refs] b/[refs] index 59527e1b8e3a..e25111dace06 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 88b8ba90570067178d32c654ad95786041e86e86 +refs/heads/master: 36149f02cb830570ca57228c8ad3d82742485eb7 diff --git a/trunk/.gitignore b/trunk/.gitignore index 869e1a3b64b6..9bb1cb6d825d 100644 --- a/trunk/.gitignore +++ b/trunk/.gitignore @@ -3,10 +3,6 @@ # subdirectories here. Add them in the ".gitignore" file # in that subdirectory instead. # -# NOTE! Please use 'git-ls-files -i --exclude-standard' -# command after changing this file, to see if there are -# any tracked files which get ignored after the change. -# # Normal rules # .* @@ -22,21 +18,19 @@ *.lst *.symtypes *.order -*.elf -*.bin -*.gz # # Top-level generic files # tags TAGS -vmlinux +vmlinux* +!vmlinux.lds.S +!vmlinux.lds.h System.map Module.markers Module.symvers !.gitignore -!.mailmap # # Generated include files diff --git a/trunk/Documentation/DocBook/kgdb.tmpl b/trunk/Documentation/DocBook/kgdb.tmpl index e8acd1f03456..028a8444d95e 100644 --- a/trunk/Documentation/DocBook/kgdb.tmpl +++ b/trunk/Documentation/DocBook/kgdb.tmpl @@ -84,9 +84,10 @@ runs an instance of gdb against the vmlinux file which contains the symbols (not boot image such as bzImage, zImage, uImage...). In gdb the developer specifies the connection parameters and - connects to kgdb. The type of connection a developer makes with - gdb depends on the availability of kgdb I/O modules compiled as - builtin's or kernel modules in the test machine's kernel. + connects to kgdb. Depending on which kgdb I/O modules exist in + the kernel for a given architecture, it may be possible to debug + the test machine's kernel with the development machine using a + rs232 or ethernet connection. @@ -222,7 +223,7 @@ IMPORTANT NOTE: Using this option with kgdb over the console - (kgdboc) is not supported. + (kgdboc) or kgdb over ethernet (kgdboe) is not supported. @@ -248,11 +249,18 @@ (gdb) target remote /dev/ttyS0 - Example (kgdb to a terminal server on tcp port 2012): + Example (kgdb to a terminal server): % gdb ./vmlinux - (gdb) target remote 192.168.2.2:2012 + (gdb) target remote udp:192.168.2.2:6443 + + + Example (kgdb over ethernet): + + + % gdb ./vmlinux + (gdb) target remote udp:192.168.2.2:6443 Once connected, you can debug a kernel the way you would debug an diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 46ece3fba6f9..5b3f31faed56 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -312,12 +312,3 @@ When: 2.6.26 Why: Implementation became generic; users should now include linux/semaphore.h instead. Who: Matthew Wilcox - ---------------------------- - -What: CONFIG_THERMAL_HWMON -When: January 2009 -Why: This option was introduced just to allow older lm-sensors userspace - to keep working over the upgrade to 2.6.26. At the scheduled time of - removal fixed lm-sensors (2.x or 3.x) should be readily available. -Who: Rene Herman diff --git a/trunk/Documentation/hwmon/sysfs-interface b/trunk/Documentation/hwmon/sysfs-interface index 2d845730d4e0..f4a8ebc1ef1a 100644 --- a/trunk/Documentation/hwmon/sysfs-interface +++ b/trunk/Documentation/hwmon/sysfs-interface @@ -2,12 +2,17 @@ Naming and data format standards for sysfs files ------------------------------------------------ The libsensors library offers an interface to the raw sensors data -through the sysfs interface. Since lm-sensors 3.0.0, libsensors is -completely chip-independent. It assumes that all the kernel drivers -implement the standard sysfs interface described in this document. -This makes adding or updating support for any given chip very easy, as -libsensors, and applications using it, do not need to be modified. -This is a major improvement compared to lm-sensors 2. +through the sysfs interface. See libsensors documentation and source for +further information. As of writing this document, libsensors +(from lm_sensors 2.8.3) is heavily chip-dependent. Adding or updating +support for any given chip requires modifying the library's code. +This is because libsensors was written for the procfs interface +older kernel modules were using, which wasn't standardized enough. +Recent versions of libsensors (from lm_sensors 2.8.2 and later) have +support for the sysfs interface, though. + +The new sysfs interface was designed to be as chip-independent as +possible. Note that motherboards vary widely in the connections to sensor chips. There is no standard that ensures, for example, that the second @@ -30,17 +35,19 @@ access this data in a simple and consistent way. That said, such programs will have to implement conversion, labeling and hiding of inputs. For this reason, it is still not recommended to bypass the library. +If you are developing a userspace application please send us feedback on +this standard. + +Note that this standard isn't completely established yet, so it is subject +to changes. If you are writing a new hardware monitoring driver those +features can't seem to fit in this interface, please contact us with your +extension proposal. Keep in mind that backward compatibility must be +preserved. + Each chip gets its own directory in the sysfs /sys/devices tree. To find all sensor chips, it is easier to follow the device symlinks from /sys/class/hwmon/hwmon*. -Up to lm-sensors 3.0.0, libsensors looks for hardware monitoring attributes -in the "physical" device directory. Since lm-sensors 3.0.1, attributes found -in the hwmon "class" device directory are also supported. Complex drivers -(e.g. drivers for multifunction chips) may want to use this possibility to -avoid namespace pollution. The only drawback will be that older versions of -libsensors won't support the driver in question. - All sysfs values are fixed point numbers. There is only one value per file, unlike the older /proc specification. diff --git a/trunk/Documentation/i2c/writing-clients b/trunk/Documentation/i2c/writing-clients index d4cd4126d1ad..ee75cbace28d 100644 --- a/trunk/Documentation/i2c/writing-clients +++ b/trunk/Documentation/i2c/writing-clients @@ -25,23 +25,12 @@ routines, and should be zero-initialized except for fields with data you provide. A client structure holds device-specific information like the driver model device node, and its I2C address. -/* iff driver uses driver model ("new style") binding model: */ - -static struct i2c_device_id foo_idtable[] = { - { "foo", my_id_for_foo }, - { "bar", my_id_for_bar }, - { } -}; - -MODULE_DEVICE_TABLE(i2c, foo_idtable); - static struct i2c_driver foo_driver = { .driver = { .name = "foo", }, /* iff driver uses driver model ("new style") binding model: */ - .id_table = foo_ids, .probe = foo_probe, .remove = foo_remove, @@ -184,9 +173,10 @@ handle may be used during foo_probe(). If foo_probe() reports success (zero not a negative status code) it may save the handle and use it until foo_remove() returns. That binding model is used by most Linux drivers. -The probe function is called when an entry in the id_table name field -matches the device's name. It is passed the entry that was matched so -the driver knows which one in the table matched. +Drivers match devices when i2c_client.driver_name and the driver name are +the same; this approach is used in several other busses that don't have +device typing support in the hardware. The driver and module name should +match, so hotplug/coldplug mechanisms will modprobe the driver. Device Creation (Standard driver model) diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index 17f1f91af35c..17a6e46fbd43 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -81,23 +81,23 @@ inet_peer_minttl - INTEGER Minimum time-to-live of entries. Should be enough to cover fragment time-to-live on the reassembling side. This minimum time-to-live is guaranteed if the pool size is less than inet_peer_threshold. - Measured in seconds. + Measured in jiffies(1). inet_peer_maxttl - INTEGER Maximum time-to-live of entries. Unused entries will expire after this period of time if there is no memory pressure on the pool (i.e. when the number of entries in the pool is very small). - Measured in seconds. + Measured in jiffies(1). inet_peer_gc_mintime - INTEGER Minimum interval between garbage collection passes. This interval is in effect under high memory pressure on the pool. - Measured in seconds. + Measured in jiffies(1). inet_peer_gc_maxtime - INTEGER Minimum interval between garbage collection passes. This interval is in effect under low (or absent) memory pressure on the pool. - Measured in seconds. + Measured in jiffies(1). TCP variables: @@ -794,6 +794,10 @@ tag - INTEGER Allows you to write a number, which can be used as required. Default value is 0. +(1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the +Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact +value on your system. + Alexey Kuznetsov. kuznet@ms2.inr.ac.ru diff --git a/trunk/Documentation/networking/s2io.txt b/trunk/Documentation/networking/s2io.txt index 1e28e2ddb90a..4bde53e85f3f 100644 --- a/trunk/Documentation/networking/s2io.txt +++ b/trunk/Documentation/networking/s2io.txt @@ -83,9 +83,9 @@ Valid range: Limited by memory on system Default: 30 e. intr_type -Specifies interrupt type. Possible values 0(INTA), 2(MSI-X) -Valid values: 0, 2 -Default: 2 +Specifies interrupt type. Possible values 1(INTA), 2(MSI), 3(MSI-X) +Valid range: 1-3 +Default: 1 5. Performance suggestions General: diff --git a/trunk/Documentation/video4linux/CARDLIST.au0828 b/trunk/Documentation/video4linux/CARDLIST.au0828 index 86d1c8e7b18f..aaae360312e4 100644 --- a/trunk/Documentation/video4linux/CARDLIST.au0828 +++ b/trunk/Documentation/video4linux/CARDLIST.au0828 @@ -1,4 +1,4 @@ 0 -> Unknown board (au0828) - 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008] + 1 -> Hauppauge HVR950Q (au0828) [2040:7200] 2 -> Hauppauge HVR850 (au0828) [2040:7240] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index e6c06fa3290e..cd587eec9fa7 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -4314,14 +4314,6 @@ L: netdev@vger.kernel.org W: http://www.linux-usb.org/usbnet S: Maintained -USB VIDEO CLASS -P: Laurent Pinchart -M: laurent.pinchart@skynet.be -L: linx-uvc-devel@berlios.de -L: video4linux-list@redhat.com -W: http://linux-uvc.berlios.de -S: Maintained - USB W996[87]CF DRIVER P: Luca Risolia M: luca.risolia@studio.unibo.it @@ -4439,10 +4431,10 @@ M: johnpol@2ka.mipt.ru S: Maintained W83791D HARDWARE MONITORING DRIVER -P: Marc Hulsman -M: m.hulsman@tudelft.nl +P: Charles Spirakis +M: bezaur@gmail.com L: lm-sensors@lm-sensors.org -S: Maintained +S: Odd Fixes W83793 HARDWARE MONITORING DRIVER P: Rudolf Marek diff --git a/trunk/Makefile b/trunk/Makefile index 6aff5f47c21d..2b4977c9844e 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 26 -EXTRAVERSION = -rc8 +EXTRAVERSION = -rc7 NAME = Rotary Wombat # *DOCUMENTATION* diff --git a/trunk/arch/alpha/Makefile b/trunk/arch/alpha/Makefile index 4759fe751aa1..4e1a8e2c4541 100644 --- a/trunk/arch/alpha/Makefile +++ b/trunk/arch/alpha/Makefile @@ -13,7 +13,6 @@ NM := $(NM) -B LDFLAGS_vmlinux := -static -N #-relax CHECKFLAGS += -D__alpha__ -m64 cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data -cflags-y += $(call cc-option, -fno-jump-tables) cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4 cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5 diff --git a/trunk/arch/alpha/kernel/core_t2.c b/trunk/arch/alpha/kernel/core_t2.c index d9980d47ab81..c0750291b44a 100644 --- a/trunk/arch/alpha/kernel/core_t2.c +++ b/trunk/arch/alpha/kernel/core_t2.c @@ -74,8 +74,6 @@ # define DBG(args) #endif -DEFINE_SPINLOCK(t2_hae_lock); - static volatile unsigned int t2_mcheck_any_expected; static volatile unsigned int t2_mcheck_last_taken; diff --git a/trunk/arch/alpha/kernel/pci.c b/trunk/arch/alpha/kernel/pci.c index 5cf45fc51343..36ab22a7ea12 100644 --- a/trunk/arch/alpha/kernel/pci.c +++ b/trunk/arch/alpha/kernel/pci.c @@ -71,23 +71,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_i static void __init quirk_cypress(struct pci_dev *dev) { - /* The Notorious Cy82C693 chip. */ - - /* The generic legacy mode IDE fixup in drivers/pci/probe.c - doesn't work correctly with the Cypress IDE controller as - it has non-standard register layout. Fix that. */ - if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) { - dev->resource[2].start = dev->resource[3].start = 0; - dev->resource[2].end = dev->resource[3].end = 0; - dev->resource[2].flags = dev->resource[3].flags = 0; - if (PCI_FUNC(dev->devfn) == 2) { - dev->resource[0].start = 0x170; - dev->resource[0].end = 0x177; - dev->resource[1].start = 0x376; - dev->resource[1].end = 0x376; - } - } - /* The Cypress bridge responds on the PCI bus in the address range 0xffff0000-0xffffffff (conventional x86 BIOS ROM). There is no way to turn this off. The bridge also supports several extended diff --git a/trunk/arch/alpha/kernel/traps.c b/trunk/arch/alpha/kernel/traps.c index c778779007fc..dc57790250d2 100644 --- a/trunk/arch/alpha/kernel/traps.c +++ b/trunk/arch/alpha/kernel/traps.c @@ -447,7 +447,7 @@ struct unaligned_stat { /* Macro for exception fixup code to access integer registers. */ -#define una_reg(r) (_regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)]) +#define una_reg(r) (regs->regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)]) asmlinkage void @@ -456,7 +456,6 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, { long error, tmp1, tmp2, tmp3, tmp4; unsigned long pc = regs->pc - 4; - unsigned long *_regs = regs->regs; const struct exception_table_entry *fixup; unaligned[0].count++; diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index 2744673314b4..52fc6a883281 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -650,8 +650,7 @@ EXPORT_SYMBOL(dma_map_sg); EXPORT_SYMBOL(dma_unmap_sg); EXPORT_SYMBOL(dma_sync_single_for_cpu); EXPORT_SYMBOL(dma_sync_single_for_device); -EXPORT_SYMBOL(dma_sync_sg_for_cpu); -EXPORT_SYMBOL(dma_sync_sg_for_device); +EXPORT_SYMBOL(dma_sync_sg); EXPORT_SYMBOL(dmabounce_register_dev); EXPORT_SYMBOL(dmabounce_unregister_dev); diff --git a/trunk/arch/arm/mach-omap1/Makefile b/trunk/arch/arm/mach-omap1/Makefile index 1bda8f5d7546..c06f5254c0f3 100644 --- a/trunk/arch/arm/mach-omap1/Makefile +++ b/trunk/arch/arm/mach-omap1/Makefile @@ -3,9 +3,7 @@ # # Common support -obj-y := io.o id.o sram.o clock.o irq.o mux.o serial.o devices.o - -obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o +obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o obj-$(CONFIG_OMAP_MPU_TIMER) += time.o obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o diff --git a/trunk/arch/arm/mach-omap1/board-osk.c b/trunk/arch/arm/mach-omap1/board-osk.c index 845c66371ca3..a66505f58b15 100644 --- a/trunk/arch/arm/mach-omap1/board-osk.c +++ b/trunk/arch/arm/mach-omap1/board-osk.c @@ -267,17 +267,13 @@ static struct i2c_board_info __initdata osk_i2c_board_info[] = { static void __init osk_init_smc91x(void) { - u32 l; - if ((gpio_request(0, "smc_irq")) < 0) { printk("Error requesting gpio 0 for smc91x irq\n"); return; } /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ - l = omap_readl(EMIFS_CCS(1)); - l |= 0x3; - omap_writel(l, EMIFS_CCS(1)); + EMIFS_CCS(1) |= 0x3; } static void __init osk_init_cf(void) @@ -530,26 +526,20 @@ static void __init osk_mistral_init(void) { } static void __init osk_init(void) { - u32 l; - /* Workaround for wrong CS3 (NOR flash) timing * There are some U-Boot versions out there which configure * wrong CS3 memory timings. This mainly leads to CRC * or similar errors if you use NOR flash (e.g. with JFFS2) */ - l = omap_readl(EMIFS_CCS(3)); - if (l != EMIFS_CS3_VAL) - omap_writel(EMIFS_CS3_VAL, EMIFS_CCS(3)); + if (EMIFS_CCS(3) != EMIFS_CS3_VAL) + EMIFS_CCS(3) = EMIFS_CS3_VAL; osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); osk_flash_resource.end += SZ_32M - 1; platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); omap_board_config = osk_config; omap_board_config_size = ARRAY_SIZE(osk_config); - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l |= (3 << 1); - omap_writel(l, USB_TRANSCEIVER_CTRL); + USB_TRANSCEIVER_CTRL_REG |= (3 << 1); /* irq for tps65010 chip */ /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */ diff --git a/trunk/arch/arm/mach-omap1/fpga.c b/trunk/arch/arm/mach-omap1/fpga.c index 0cf62ef5ecb7..30e188109046 100644 --- a/trunk/arch/arm/mach-omap1/fpga.c +++ b/trunk/arch/arm/mach-omap1/fpga.c @@ -32,7 +32,7 @@ static void fpga_mask_irq(unsigned int irq) { - irq -= OMAP_FPGA_IRQ_BASE; + irq -= OMAP1510_IH_FPGA_BASE; if (irq < 8) __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) @@ -65,7 +65,7 @@ static void fpga_ack_irq(unsigned int irq) static void fpga_unmask_irq(unsigned int irq) { - irq -= OMAP_FPGA_IRQ_BASE; + irq -= OMAP1510_IH_FPGA_BASE; if (irq < 8) __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)), @@ -95,8 +95,8 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc) if (!stat) return; - for (fpga_irq = OMAP_FPGA_IRQ_BASE; - (fpga_irq < OMAP_FPGA_IRQ_END) && stat; + for (fpga_irq = OMAP1510_IH_FPGA_BASE; + (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat; fpga_irq++, stat >>= 1) { if (stat & 1) { d = irq_desc + fpga_irq; @@ -151,7 +151,7 @@ void omap1510_fpga_init_irq(void) __raw_writeb(0, OMAP1510_FPGA_IMR_HI); __raw_writeb(0, INNOVATOR_FPGA_IMR2); - for (i = OMAP_FPGA_IRQ_BASE; i < OMAP_FPGA_IRQ_END; i++) { + for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) { if (i == OMAP1510_INT_FPGA_TS) { /* diff --git a/trunk/arch/arm/mach-omap1/mcbsp.c b/trunk/arch/arm/mach-omap1/mcbsp.c deleted file mode 100644 index 2d2c2522b048..000000000000 --- a/trunk/arch/arm/mach-omap1/mcbsp.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * linux/arch/arm/mach-omap1/mcbsp.c - * - * Copyright (C) 2008 Instituto Nokia de Tecnologia - * Contact: Eduardo Valentin - * - * 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. - * - * Multichannel mode not supported. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define DPS_RSTCT2_PER_EN (1 << 0) -#define DSP_RSTCT2_WD_PER_EN (1 << 1) - -struct mcbsp_internal_clk { - struct clk clk; - struct clk **childs; - int n_childs; -}; - -#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) -static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) -{ - const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" }; - int i; - - mclk->n_childs = ARRAY_SIZE(clk_names); - mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), - GFP_KERNEL); - - for (i = 0; i < mclk->n_childs; i++) { - /* We fake a platform device to get correct device id */ - struct platform_device pdev; - - pdev.dev.bus = &platform_bus_type; - pdev.id = mclk->clk.id; - mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); - if (IS_ERR(mclk->childs[i])) - printk(KERN_ERR "Could not get clock %s (%d).\n", - clk_names[i], mclk->clk.id); - } -} - -static int omap_mcbsp_clk_enable(struct clk *clk) -{ - struct mcbsp_internal_clk *mclk = container_of(clk, - struct mcbsp_internal_clk, clk); - int i; - - for (i = 0; i < mclk->n_childs; i++) - clk_enable(mclk->childs[i]); - return 0; -} - -static void omap_mcbsp_clk_disable(struct clk *clk) -{ - struct mcbsp_internal_clk *mclk = container_of(clk, - struct mcbsp_internal_clk, clk); - int i; - - for (i = 0; i < mclk->n_childs; i++) - clk_disable(mclk->childs[i]); -} - -static struct mcbsp_internal_clk omap_mcbsp_clks[] = { - { - .clk = { - .name = "mcbsp_clk", - .id = 1, - .enable = omap_mcbsp_clk_enable, - .disable = omap_mcbsp_clk_disable, - }, - }, - { - .clk = { - .name = "mcbsp_clk", - .id = 3, - .enable = omap_mcbsp_clk_enable, - .disable = omap_mcbsp_clk_disable, - }, - }, -}; - -#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) -#else -#define omap_mcbsp_clks_size 0 -static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; -static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) -{ } -#endif - -static int omap1_mcbsp_check(unsigned int id) -{ - /* REVISIT: Check correctly for number of registered McBSPs */ - if (cpu_is_omap730()) { - if (id > OMAP_MAX_MCBSP_COUNT - 2) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", - id + 1); - return -ENODEV; - } - return 0; - } - - if (cpu_is_omap15xx() || cpu_is_omap16xx()) { - if (id > OMAP_MAX_MCBSP_COUNT - 1) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", - id + 1); - return -ENODEV; - } - return 0; - } - - return -ENODEV; -} - -static void omap1_mcbsp_request(unsigned int id) -{ - /* - * On 1510, 1610 and 1710, McBSP1 and McBSP3 - * are DSP public peripherals. - */ - if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) { - omap_dsp_request_mem(); - /* - * DSP external peripheral reset - * FIXME: This should be moved to dsp code - */ - __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN | - DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2); - } -} - -static void omap1_mcbsp_free(unsigned int id) -{ - if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) - omap_dsp_release_mem(); -} - -static struct omap_mcbsp_ops omap1_mcbsp_ops = { - .check = omap1_mcbsp_check, - .request = omap1_mcbsp_request, - .free = omap1_mcbsp_free, -}; - -#ifdef CONFIG_ARCH_OMAP730 -static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = { - { - .virt_base = io_p2v(OMAP730_MCBSP1_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP_DMA_MCBSP1_TX, - .rx_irq = INT_730_McBSP1RX, - .tx_irq = INT_730_McBSP1TX, - .ops = &omap1_mcbsp_ops, - }, - { - .virt_base = io_p2v(OMAP730_MCBSP2_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP_DMA_MCBSP3_TX, - .rx_irq = INT_730_McBSP2RX, - .tx_irq = INT_730_McBSP2TX, - .ops = &omap1_mcbsp_ops, - }, -}; -#define OMAP730_MCBSP_PDATA_SZ ARRAY_SIZE(omap730_mcbsp_pdata) -#else -#define omap730_mcbsp_pdata NULL -#define OMAP730_MCBSP_PDATA_SZ 0 -#endif - -#ifdef CONFIG_ARCH_OMAP15XX -static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { - { - .virt_base = OMAP1510_MCBSP1_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP_DMA_MCBSP1_TX, - .rx_irq = INT_McBSP1RX, - .tx_irq = INT_McBSP1TX, - .ops = &omap1_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .virt_base = io_p2v(OMAP1510_MCBSP2_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP_DMA_MCBSP2_TX, - .rx_irq = INT_1510_SPI_RX, - .tx_irq = INT_1510_SPI_TX, - .ops = &omap1_mcbsp_ops, - }, - { - .virt_base = OMAP1510_MCBSP3_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP_DMA_MCBSP3_TX, - .rx_irq = INT_McBSP3RX, - .tx_irq = INT_McBSP3TX, - .ops = &omap1_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, -}; -#define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata) -#else -#define omap15xx_mcbsp_pdata NULL -#define OMAP15XX_MCBSP_PDATA_SZ 0 -#endif - -#ifdef CONFIG_ARCH_OMAP16XX -static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { - { - .virt_base = OMAP1610_MCBSP1_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP_DMA_MCBSP1_TX, - .rx_irq = INT_McBSP1RX, - .tx_irq = INT_McBSP1TX, - .ops = &omap1_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .virt_base = io_p2v(OMAP1610_MCBSP2_BASE), - .dma_rx_sync = OMAP_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP_DMA_MCBSP2_TX, - .rx_irq = INT_1610_McBSP2_RX, - .tx_irq = INT_1610_McBSP2_TX, - .ops = &omap1_mcbsp_ops, - }, - { - .virt_base = OMAP1610_MCBSP3_BASE, - .dma_rx_sync = OMAP_DMA_MCBSP3_RX, - .dma_tx_sync = OMAP_DMA_MCBSP3_TX, - .rx_irq = INT_McBSP3RX, - .tx_irq = INT_McBSP3TX, - .ops = &omap1_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, -}; -#define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata) -#else -#define omap16xx_mcbsp_pdata NULL -#define OMAP16XX_MCBSP_PDATA_SZ 0 -#endif - -int __init omap1_mcbsp_init(void) -{ - int i; - - for (i = 0; i < omap_mcbsp_clks_size; i++) { - if (cpu_is_omap15xx() || cpu_is_omap16xx()) { - omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); - clk_register(&omap_mcbsp_clks[i].clk); - } - } - - if (cpu_is_omap730()) - omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata, - OMAP730_MCBSP_PDATA_SZ); - - if (cpu_is_omap15xx()) - omap_mcbsp_register_board_cfg(omap15xx_mcbsp_pdata, - OMAP15XX_MCBSP_PDATA_SZ); - - if (cpu_is_omap16xx()) - omap_mcbsp_register_board_cfg(omap16xx_mcbsp_pdata, - OMAP16XX_MCBSP_PDATA_SZ); - - return omap_mcbsp_init(); -} - -arch_initcall(omap1_mcbsp_init); diff --git a/trunk/arch/arm/mach-omap2/Makefile b/trunk/arch/arm/mach-omap2/Makefile index 93ee990618ef..2feb6870b735 100644 --- a/trunk/arch/arm/mach-omap2/Makefile +++ b/trunk/arch/arm/mach-omap2/Makefile @@ -3,15 +3,9 @@ # # Common support -obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ +obj-y := irq.o id.o io.o sram-fn.o memory.o control.o prcm.o clock.o mux.o \ devices.o serial.o gpmc.o timer-gp.o -obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o - -# Functions loaded to SRAM -obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o -obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o - # Power Management obj-$(CONFIG_PM) += pm.o sleep.o diff --git a/trunk/arch/arm/mach-omap2/clock.c b/trunk/arch/arm/mach-omap2/clock.c index 15675bce8012..ab9fc57d25f1 100644 --- a/trunk/arch/arm/mach-omap2/clock.c +++ b/trunk/arch/arm/mach-omap2/clock.c @@ -41,24 +41,6 @@ #define MAX_CLOCK_ENABLE_WAIT 100000 -/* DPLL rate rounding: minimum DPLL multiplier, divider values */ -#define DPLL_MIN_MULTIPLIER 1 -#define DPLL_MIN_DIVIDER 1 - -/* Possible error results from _dpll_test_mult */ -#define DPLL_MULT_UNDERFLOW (1 << 0) - -/* - * Scale factor to mitigate roundoff errors in DPLL rate rounding. - * The higher the scale factor, the greater the risk of arithmetic overflow, - * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR - * must be a power of DPLL_SCALE_BASE. - */ -#define DPLL_SCALE_FACTOR 64 -#define DPLL_SCALE_BASE 2 -#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ - (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) - u8 cpu_mask; /*------------------------------------------------------------------------- @@ -113,7 +95,7 @@ u32 omap2_get_dpll_rate(struct clk *clk) { long long dpll_clk; u32 dpll_mult, dpll_div, dpll; - struct dpll_data *dd; + const struct dpll_data *dd; dd = clk->dpll_data; /* REVISIT: What do we return on error? */ @@ -621,8 +603,7 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) clk->rate = clk->parent->rate / new_div; if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { - prm_write_mod_reg(OMAP24XX_VALID_CONFIG, - OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET); + __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL); wmb(); } @@ -742,184 +723,6 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) return 0; } -/* DPLL rate rounding code */ - -/** - * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding - * @clk: struct clk * of the DPLL - * @tolerance: maximum rate error tolerance - * - * Set the maximum DPLL rate error tolerance for the rate rounding - * algorithm. The rate tolerance is an attempt to balance DPLL power - * saving (the least divider value "n") vs. rate fidelity (the least - * difference between the desired DPLL target rate and the rounded - * rate out of the algorithm). So, increasing the tolerance is likely - * to decrease DPLL power consumption and increase DPLL rate error. - * Returns -EINVAL if provided a null clock ptr or a clk that is not a - * DPLL; or 0 upon success. - */ -int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance) -{ - if (!clk || !clk->dpll_data) - return -EINVAL; - - clk->dpll_data->rate_tolerance = tolerance; - - return 0; -} - -static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n) -{ - unsigned long long num; - - num = (unsigned long long)parent_rate * m; - do_div(num, n); - return num; -} - -/* - * _dpll_test_mult - test a DPLL multiplier value - * @m: pointer to the DPLL m (multiplier) value under test - * @n: current DPLL n (divider) value under test - * @new_rate: pointer to storage for the resulting rounded rate - * @target_rate: the desired DPLL rate - * @parent_rate: the DPLL's parent clock rate - * - * This code tests a DPLL multiplier value, ensuring that the - * resulting rate will not be higher than the target_rate, and that - * the multiplier value itself is valid for the DPLL. Initially, the - * integer pointed to by the m argument should be prescaled by - * multiplying by DPLL_SCALE_FACTOR. The code will replace this with - * a non-scaled m upon return. This non-scaled m will result in a - * new_rate as close as possible to target_rate (but not greater than - * target_rate) given the current (parent_rate, n, prescaled m) - * triple. Returns DPLL_MULT_UNDERFLOW in the event that the - * non-scaled m attempted to underflow, which can allow the calling - * function to bail out early; or 0 upon success. - */ -static int _dpll_test_mult(int *m, int n, unsigned long *new_rate, - unsigned long target_rate, - unsigned long parent_rate) -{ - int flags = 0, carry = 0; - - /* Unscale m and round if necessary */ - if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL) - carry = 1; - *m = (*m / DPLL_SCALE_FACTOR) + carry; - - /* - * The new rate must be <= the target rate to avoid programming - * a rate that is impossible for the hardware to handle - */ - *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); - if (*new_rate > target_rate) { - (*m)--; - *new_rate = 0; - } - - /* Guard against m underflow */ - if (*m < DPLL_MIN_MULTIPLIER) { - *m = DPLL_MIN_MULTIPLIER; - *new_rate = 0; - flags = DPLL_MULT_UNDERFLOW; - } - - if (*new_rate == 0) - *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); - - return flags; -} - -/** - * omap2_dpll_round_rate - round a target rate for an OMAP DPLL - * @clk: struct clk * for a DPLL - * @target_rate: desired DPLL clock rate - * - * Given a DPLL, a desired target rate, and a rate tolerance, round - * the target rate to a possible, programmable rate for this DPLL. - * Rate tolerance is assumed to be set by the caller before this - * function is called. Attempts to select the minimum possible n - * within the tolerance to reduce power consumption. Stores the - * computed (m, n) in the DPLL's dpll_data structure so set_rate() - * will not need to call this (expensive) function again. Returns ~0 - * if the target rate cannot be rounded, either because the rate is - * too low or because the rate tolerance is set too tightly; or the - * rounded rate upon success. - */ -long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) -{ - int m, n, r, e, scaled_max_m; - unsigned long scaled_rt_rp, new_rate; - int min_e = -1, min_e_m = -1, min_e_n = -1; - - if (!clk || !clk->dpll_data) - return ~0; - - pr_debug("clock: starting DPLL round_rate for clock %s, target rate " - "%ld\n", clk->name, target_rate); - - scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR); - scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR; - - clk->dpll_data->last_rounded_rate = 0; - - for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) { - - /* Compute the scaled DPLL multiplier, based on the divider */ - m = scaled_rt_rp * n; - - /* - * Since we're counting n down, a m overflow means we can - * can immediately skip to the next n - */ - if (m > scaled_max_m) - continue; - - r = _dpll_test_mult(&m, n, &new_rate, target_rate, - clk->parent->rate); - - e = target_rate - new_rate; - pr_debug("clock: n = %d: m = %d: rate error is %d " - "(new_rate = %ld)\n", n, m, e, new_rate); - - if (min_e == -1 || - min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) { - min_e = e; - min_e_m = m; - min_e_n = n; - - pr_debug("clock: found new least error %d\n", min_e); - } - - /* - * Since we're counting n down, a m underflow means we - * can bail out completely (since as n decreases in - * the next iteration, there's no way that m can - * increase beyond the current m) - */ - if (r & DPLL_MULT_UNDERFLOW) - break; - } - - if (min_e < 0) { - pr_debug("clock: error: target rate or tolerance too low\n"); - return ~0; - } - - clk->dpll_data->last_rounded_m = min_e_m; - clk->dpll_data->last_rounded_n = min_e_n; - clk->dpll_data->last_rounded_rate = - _dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n); - - pr_debug("clock: final least error: e = %d, m = %d, n = %d\n", - min_e, min_e_m, min_e_n); - pr_debug("clock: final rate: %ld (target rate: %ld)\n", - clk->dpll_data->last_rounded_rate, target_rate); - - return clk->dpll_data->last_rounded_rate; -} - /*------------------------------------------------------------------------- * Omap2 clock reset and init functions *-------------------------------------------------------------------------*/ diff --git a/trunk/arch/arm/mach-omap2/clock.h b/trunk/arch/arm/mach-omap2/clock.h index 3cd37cb57c5a..d5980a9e09a4 100644 --- a/trunk/arch/arm/mach-omap2/clock.h +++ b/trunk/arch/arm/mach-omap2/clock.h @@ -18,16 +18,11 @@ #include -/* The maximum error between a target DPLL rate and the rounded rate in Hz */ -#define DEFAULT_DPLL_RATE_TOLERANCE 50000 - int omap2_clk_enable(struct clk *clk); void omap2_clk_disable(struct clk *clk); long omap2_clk_round_rate(struct clk *clk, unsigned long rate); int omap2_clk_set_rate(struct clk *clk, unsigned long rate); int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent); -int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance); -long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate); #ifdef CONFIG_OMAP_RESET_CLOCKS void omap2_clk_disable_unused(struct clk *clk); @@ -47,7 +42,6 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate); int omap2_clksel_set_rate(struct clk *clk, unsigned long rate); u32 omap2_get_dpll_rate(struct clk *clk); int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); -void omap2_clk_prepare_for_reboot(void); extern u8 cpu_mask; diff --git a/trunk/arch/arm/mach-omap2/clock24xx.c b/trunk/arch/arm/mach-omap2/clock24xx.c index aa567876651d..ece32d8acba4 100644 --- a/trunk/arch/arm/mach-omap2/clock24xx.c +++ b/trunk/arch/arm/mach-omap2/clock24xx.c @@ -154,7 +154,7 @@ static void omap2_clk_fixed_disable(struct clk *clk) * Uses the current prcm set to tell if a rate is valid. * You can go slower, but not faster within a given rate set. */ -long omap2_dpllcore_round_rate(unsigned long target_rate) +static u32 omap2_dpll_round_rate(unsigned long target_rate) { u32 high, low, core_clk_src; @@ -183,14 +183,14 @@ long omap2_dpllcore_round_rate(unsigned long target_rate) } -static void omap2_dpllcore_recalc(struct clk *clk) +static void omap2_dpll_recalc(struct clk *clk) { clk->rate = omap2_get_dpll_rate_24xx(clk); propagate_rate(clk); } -static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) +static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate) { u32 cur_rate, low, mult, div, valid_rate, done_rate; u32 bypass = 0; @@ -209,7 +209,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) } else if ((rate == (cur_rate * 2)) && (mult == 1)) { omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); } else if (rate != cur_rate) { - valid_rate = omap2_dpllcore_round_rate(rate); + valid_rate = omap2_dpll_round_rate(rate); if (valid_rate != rate) goto dpll_exit; @@ -256,7 +256,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) omap2_init_memory_params(omap2_dll_force_needed()); omap2_reprogram_sdrc(done_rate, 0); } - omap2_dpllcore_recalc(&dpll_ck); + omap2_dpll_recalc(&dpll_ck); ret = 0; dpll_exit: @@ -383,7 +383,7 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate) local_irq_restore(flags); } - omap2_dpllcore_recalc(&dpll_ck); + omap2_dpll_recalc(&dpll_ck); return 0; } diff --git a/trunk/arch/arm/mach-omap2/clock24xx.h b/trunk/arch/arm/mach-omap2/clock24xx.h index be4e25554e05..88081ed13f96 100644 --- a/trunk/arch/arm/mach-omap2/clock24xx.h +++ b/trunk/arch/arm/mach-omap2/clock24xx.h @@ -30,12 +30,12 @@ static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate); static void omap2_sys_clk_recalc(struct clk *clk); static void omap2_osc_clk_recalc(struct clk *clk); static void omap2_sys_clk_recalc(struct clk *clk); -static void omap2_dpllcore_recalc(struct clk *clk); +static void omap2_dpll_recalc(struct clk *clk); static int omap2_clk_fixed_enable(struct clk *clk); static void omap2_clk_fixed_disable(struct clk *clk); static int omap2_enable_osc_ck(struct clk *clk); static void omap2_disable_osc_ck(struct clk *clk); -static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate); +static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate); /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP @@ -665,27 +665,20 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */ * deal with this */ -static struct dpll_data dpll_dd = { +static const struct dpll_data dpll_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .mult_mask = OMAP24XX_DPLL_MULT_MASK, .div1_mask = OMAP24XX_DPLL_DIV_MASK, - .max_multiplier = 1024, - .max_divider = 16, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; -/* - * XXX Cannot add round_rate here yet, as this is still a composite clock, - * not just a DPLL - */ static struct clk dpll_ck = { .name = "dpll_ck", .parent = &sys_ck, /* Can be func_32k also */ .dpll_data = &dpll_dd, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_PROPAGATES | ALWAYS_ENABLED, - .recalc = &omap2_dpllcore_recalc, - .set_rate = &omap2_reprogram_dpllcore, + .recalc = &omap2_dpll_recalc, + .set_rate = &omap2_reprogram_dpll, }; static struct clk apll96_ck = { @@ -1754,8 +1747,7 @@ static struct clk gpt12_fck = { }; static struct clk mcbsp1_ick = { - .name = "mcbsp_ick", - .id = 1, + .name = "mcbsp1_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1764,8 +1756,7 @@ static struct clk mcbsp1_ick = { }; static struct clk mcbsp1_fck = { - .name = "mcbsp_fck", - .id = 1, + .name = "mcbsp1_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), @@ -1774,8 +1765,7 @@ static struct clk mcbsp1_fck = { }; static struct clk mcbsp2_ick = { - .name = "mcbsp_ick", - .id = 2, + .name = "mcbsp2_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), @@ -1784,8 +1774,7 @@ static struct clk mcbsp2_ick = { }; static struct clk mcbsp2_fck = { - .name = "mcbsp_fck", - .id = 2, + .name = "mcbsp2_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), @@ -1794,8 +1783,7 @@ static struct clk mcbsp2_fck = { }; static struct clk mcbsp3_ick = { - .name = "mcbsp_ick", - .id = 3, + .name = "mcbsp3_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1804,8 +1792,7 @@ static struct clk mcbsp3_ick = { }; static struct clk mcbsp3_fck = { - .name = "mcbsp_fck", - .id = 3, + .name = "mcbsp3_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), @@ -1814,8 +1801,7 @@ static struct clk mcbsp3_fck = { }; static struct clk mcbsp4_ick = { - .name = "mcbsp_ick", - .id = 4, + .name = "mcbsp4_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1824,8 +1810,7 @@ static struct clk mcbsp4_ick = { }; static struct clk mcbsp4_fck = { - .name = "mcbsp_fck", - .id = 4, + .name = "mcbsp4_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), @@ -1834,8 +1819,7 @@ static struct clk mcbsp4_fck = { }; static struct clk mcbsp5_ick = { - .name = "mcbsp_ick", - .id = 5, + .name = "mcbsp5_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), @@ -1844,8 +1828,7 @@ static struct clk mcbsp5_ick = { }; static struct clk mcbsp5_fck = { - .name = "mcbsp_fck", - .id = 5, + .name = "mcbsp5_fck", .parent = &func_96m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), diff --git a/trunk/arch/arm/mach-omap2/clock34xx.c b/trunk/arch/arm/mach-omap2/clock34xx.c index 4263099b1ad3..b42bdd6079a5 100644 --- a/trunk/arch/arm/mach-omap2/clock34xx.c +++ b/trunk/arch/arm/mach-omap2/clock34xx.c @@ -1,11 +1,10 @@ /* * OMAP3-specific clock framework functions * - * Copyright (C) 2007-2008 Texas Instruments, Inc. - * Copyright (C) 2007-2008 Nokia Corporation + * Copyright (C) 2007 Texas Instruments, Inc. + * Copyright (C) 2007 Nokia Corporation * * Written by Paul Walmsley - * Testing and integration fixes by Jouni Högander * * Parts of this code are based on code written by * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu @@ -24,7 +23,6 @@ #include #include #include -#include #include #include @@ -39,11 +37,8 @@ #include "cm.h" #include "cm-regbits-34xx.h" -/* CM_AUTOIDLE_PLL*.AUTO_* bit values */ -#define DPLL_AUTOIDLE_DISABLE 0x0 -#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1 - -#define MAX_DPLL_WAIT_TRIES 1000000 +/* CM_CLKEN_PLL*.EN* bit values */ +#define DPLL_LOCKED 0x7 /** * omap3_dpll_recalc - recalculate DPLL rate @@ -58,290 +53,6 @@ static void omap3_dpll_recalc(struct clk *clk) propagate_rate(clk); } -/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */ -static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits) -{ - const struct dpll_data *dd; - - dd = clk->dpll_data; - - cm_rmw_reg_bits(dd->enable_mask, clken_bits << __ffs(dd->enable_mask), - dd->control_reg); -} - -/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */ -static int _omap3_wait_dpll_status(struct clk *clk, u8 state) -{ - const struct dpll_data *dd; - int i = 0; - int ret = -EINVAL; - u32 idlest_mask; - - dd = clk->dpll_data; - - state <<= dd->idlest_bit; - idlest_mask = 1 << dd->idlest_bit; - - while (((cm_read_reg(dd->idlest_reg) & idlest_mask) != state) && - i < MAX_DPLL_WAIT_TRIES) { - i++; - udelay(1); - } - - if (i == MAX_DPLL_WAIT_TRIES) { - printk(KERN_ERR "clock: %s failed transition to '%s'\n", - clk->name, (state) ? "locked" : "bypassed"); - } else { - pr_debug("clock: %s transition to '%s' in %d loops\n", - clk->name, (state) ? "locked" : "bypassed", i); - - ret = 0; - } - - return ret; -} - -/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */ - -/* - * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report - * readiness before returning. Will save and restore the DPLL's - * autoidle state across the enable, per the CDP code. If the DPLL - * locked successfully, return 0; if the DPLL did not lock in the time - * allotted, or DPLL3 was passed in, return -EINVAL. - */ -static int _omap3_noncore_dpll_lock(struct clk *clk) -{ - u8 ai; - int r; - - if (clk == &dpll3_ck) - return -EINVAL; - - pr_debug("clock: locking DPLL %s\n", clk->name); - - ai = omap3_dpll_autoidle_read(clk); - - _omap3_dpll_write_clken(clk, DPLL_LOCKED); - - if (ai) { - /* - * If no downstream clocks are enabled, CM_IDLEST bit - * may never become active, so don't wait for DPLL to lock. - */ - r = 0; - omap3_dpll_allow_idle(clk); - } else { - r = _omap3_wait_dpll_status(clk, 1); - omap3_dpll_deny_idle(clk); - }; - - return r; -} - -/* - * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to enter low-power bypass mode. In - * bypass mode, the DPLL's rate is set equal to its parent clock's - * rate. Waits for the DPLL to report readiness before returning. - * Will save and restore the DPLL's autoidle state across the enable, - * per the CDP code. If the DPLL entered bypass mode successfully, - * return 0; if the DPLL did not enter bypass in the time allotted, or - * DPLL3 was passed in, or the DPLL does not support low-power bypass, - * return -EINVAL. - */ -static int _omap3_noncore_dpll_bypass(struct clk *clk) -{ - int r; - u8 ai; - - if (clk == &dpll3_ck) - return -EINVAL; - - if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) - return -EINVAL; - - pr_debug("clock: configuring DPLL %s for low-power bypass\n", - clk->name); - - ai = omap3_dpll_autoidle_read(clk); - - _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS); - - r = _omap3_wait_dpll_status(clk, 0); - - if (ai) - omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); - - return r; -} - -/* - * _omap3_noncore_dpll_stop - instruct a DPLL to stop - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to enter low-power stop. Will save and - * restore the DPLL's autoidle state across the stop, per the CDP - * code. If DPLL3 was passed in, or the DPLL does not support - * low-power stop, return -EINVAL; otherwise, return 0. - */ -static int _omap3_noncore_dpll_stop(struct clk *clk) -{ - u8 ai; - - if (clk == &dpll3_ck) - return -EINVAL; - - if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP))) - return -EINVAL; - - pr_debug("clock: stopping DPLL %s\n", clk->name); - - ai = omap3_dpll_autoidle_read(clk); - - _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP); - - if (ai) - omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); - - return 0; -} - -/** - * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. - * The choice of modes depends on the DPLL's programmed rate: if it is - * the same as the DPLL's parent clock, it will enter bypass; - * otherwise, it will enter lock. This code will wait for the DPLL to - * indicate readiness before returning, unless the DPLL takes too long - * to enter the target state. Intended to be used as the struct clk's - * enable function. If DPLL3 was passed in, or the DPLL does not - * support low-power stop, or if the DPLL took too long to enter - * bypass or lock, return -EINVAL; otherwise, return 0. - */ -static int omap3_noncore_dpll_enable(struct clk *clk) -{ - int r; - - if (clk == &dpll3_ck) - return -EINVAL; - - if (clk->parent->rate == clk_get_rate(clk)) - r = _omap3_noncore_dpll_bypass(clk); - else - r = _omap3_noncore_dpll_lock(clk); - - return r; -} - -/** - * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode - * @clk: pointer to a DPLL struct clk - * - * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. - * The choice of modes depends on the DPLL's programmed rate: if it is - * the same as the DPLL's parent clock, it will enter bypass; - * otherwise, it will enter lock. This code will wait for the DPLL to - * indicate readiness before returning, unless the DPLL takes too long - * to enter the target state. Intended to be used as the struct clk's - * enable function. If DPLL3 was passed in, or the DPLL does not - * support low-power stop, or if the DPLL took too long to enter - * bypass or lock, return -EINVAL; otherwise, return 0. - */ -static void omap3_noncore_dpll_disable(struct clk *clk) -{ - if (clk == &dpll3_ck) - return; - - _omap3_noncore_dpll_stop(clk); -} - -/** - * omap3_dpll_autoidle_read - read a DPLL's autoidle bits - * @clk: struct clk * of the DPLL to read - * - * Return the DPLL's autoidle bits, shifted down to bit 0. Returns - * -EINVAL if passed a null pointer or if the struct clk does not - * appear to refer to a DPLL. - */ -static u32 omap3_dpll_autoidle_read(struct clk *clk) -{ - const struct dpll_data *dd; - u32 v; - - if (!clk || !clk->dpll_data) - return -EINVAL; - - dd = clk->dpll_data; - - v = cm_read_reg(dd->autoidle_reg); - v &= dd->autoidle_mask; - v >>= __ffs(dd->autoidle_mask); - - return v; -} - -/** - * omap3_dpll_allow_idle - enable DPLL autoidle bits - * @clk: struct clk * of the DPLL to operate on - * - * Enable DPLL automatic idle control. This automatic idle mode - * switching takes effect only when the DPLL is locked, at least on - * OMAP3430. The DPLL will enter low-power stop when its downstream - * clocks are gated. No return value. - */ -static void omap3_dpll_allow_idle(struct clk *clk) -{ - const struct dpll_data *dd; - - if (!clk || !clk->dpll_data) - return; - - dd = clk->dpll_data; - - /* - * REVISIT: CORE DPLL can optionally enter low-power bypass - * by writing 0x5 instead of 0x1. Add some mechanism to - * optionally enter this mode. - */ - cm_rmw_reg_bits(dd->autoidle_mask, - DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask), - dd->autoidle_reg); -} - -/** - * omap3_dpll_deny_idle - prevent DPLL from automatically idling - * @clk: struct clk * of the DPLL to operate on - * - * Disable DPLL automatic idle control. No return value. - */ -static void omap3_dpll_deny_idle(struct clk *clk) -{ - const struct dpll_data *dd; - - if (!clk || !clk->dpll_data) - return; - - dd = clk->dpll_data; - - cm_rmw_reg_bits(dd->autoidle_mask, - DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask), - dd->autoidle_reg); -} - -/* Clock control for DPLL outputs */ - /** * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate * @clk: DPLL output struct clk @@ -378,8 +89,6 @@ static void omap3_clkoutx2_recalc(struct clk *clk) propagate_rate(clk); } -/* Common clock code */ - /* * As it is structured now, this will prevent an OMAP2/3 multiboot * kernel from compiling. This will need further attention. diff --git a/trunk/arch/arm/mach-omap2/clock34xx.h b/trunk/arch/arm/mach-omap2/clock34xx.h index 05757eb032bc..c9c5972a2e25 100644 --- a/trunk/arch/arm/mach-omap2/clock34xx.h +++ b/trunk/arch/arm/mach-omap2/clock34xx.h @@ -1,19 +1,14 @@ /* * OMAP3 clock framework * + * Virtual clocks are introduced as a convenient tools. + * They are sources for other clocks and not supposed + * to be requested from drivers directly. + * * Copyright (C) 2007-2008 Texas Instruments, Inc. * Copyright (C) 2007-2008 Nokia Corporation * * Written by Paul Walmsley - * With many device clock fixes by Kevin Hilman and Jouni Högander - * DPLL bypass clock support added by Roman Tereshonkov - * - */ - -/* - * Virtual clocks are introduced as convenient tools. - * They are sources for other clocks and not supposed - * to be requested from drivers directly. */ #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H @@ -29,15 +24,6 @@ static void omap3_dpll_recalc(struct clk *clk); static void omap3_clkoutx2_recalc(struct clk *clk); -static void omap3_dpll_allow_idle(struct clk *clk); -static void omap3_dpll_deny_idle(struct clk *clk); -static u32 omap3_dpll_autoidle_read(struct clk *clk); -static int omap3_noncore_dpll_enable(struct clk *clk); -static void omap3_noncore_dpll_disable(struct clk *clk); - -/* Maximum DPLL multiplier, divider values for OMAP3 */ -#define OMAP3_MAX_DPLL_MULT 2048 -#define OMAP3_MAX_DPLL_DIV 128 /* * DPLL1 supplies clock to the MPU. @@ -47,11 +33,6 @@ static void omap3_noncore_dpll_disable(struct clk *clk); * DPLL5 supplies other peripheral clocks (USBHOST, USIM). */ -/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ -#define DPLL_LOW_POWER_STOP 0x1 -#define DPLL_LOW_POWER_BYPASS 0x5 -#define DPLL_LOCKED 0x7 - /* PRM CLOCKS */ /* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */ @@ -259,23 +240,15 @@ static const struct clksel_rate div16_dpll_rates[] = { /* DPLL1 */ /* MPU clock source */ /* Type: DPLL */ -static struct dpll_data dpll1_dd = { +static const struct dpll_data dpll1_dd = { .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK, .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL), .enable_mask = OMAP3430_EN_MPU_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), .auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL), - .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), - .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll1_ck = { @@ -283,7 +256,6 @@ static struct clk dpll1_ck = { .parent = &sys_ck, .dpll_data = &dpll1_dd, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .round_rate = &omap2_dpll_round_rate, .recalc = &omap3_dpll_recalc, }; @@ -325,34 +297,22 @@ static struct clk dpll1_x2m2_ck = { /* IVA2 clock source */ /* Type: DPLL */ -static struct dpll_data dpll2_dd = { +static const struct dpll_data dpll2_dd = { .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK, .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL), .enable_mask = OMAP3430_EN_IVA2_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | - (1 << DPLL_LOW_POWER_BYPASS), .auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL), - .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), - .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll2_ck = { .name = "dpll2_ck", .parent = &sys_ck, .dpll_data = &dpll2_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .enable = &omap3_noncore_dpll_enable, - .disable = &omap3_noncore_dpll_disable, - .round_rate = &omap2_dpll_round_rate, + .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, .recalc = &omap3_dpll_recalc, }; @@ -378,12 +338,10 @@ static struct clk dpll2_m2_ck = { .recalc = &omap2_clksel_recalc, }; -/* - * DPLL3 - * Source clock for all interfaces and for some device fclks - * REVISIT: Also supports fast relock bypass - not included below - */ -static struct dpll_data dpll3_dd = { +/* DPLL3 */ +/* Source clock for all interfaces and for some device fclks */ +/* Type: DPLL */ +static const struct dpll_data dpll3_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK, @@ -392,11 +350,6 @@ static struct dpll_data dpll3_dd = { .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), - .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll3_ck = { @@ -404,7 +357,6 @@ static struct clk dpll3_ck = { .parent = &sys_ck, .dpll_data = &dpll3_dd, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, - .round_rate = &omap2_dpll_round_rate, .recalc = &omap3_dpll_recalc, }; @@ -487,7 +439,7 @@ static struct clk core_ck = { .name = "core_ck", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, + .clksel_mask = OMAP3430_ST_CORE_CLK, .clksel = core_ck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -504,7 +456,7 @@ static struct clk dpll3_m2x2_ck = { .name = "dpll3_m2x2_ck", .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, + .clksel_mask = OMAP3430_ST_CORE_CLK, .clksel = dpll3_m2x2_ck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -551,7 +503,7 @@ static struct clk emu_core_alwon_ck = { .parent = &dpll3_m3x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, + .clksel_mask = OMAP3430_ST_CORE_CLK, .clksel = emu_core_alwon_ck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -561,33 +513,22 @@ static struct clk emu_core_alwon_ck = { /* DPLL4 */ /* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ /* Type: DPLL */ -static struct dpll_data dpll4_dd = { +static const struct dpll_data dpll4_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), - .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll4_ck = { .name = "dpll4_ck", .parent = &sys_ck, .dpll_data = &dpll4_dd, - .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, - .enable = &omap3_noncore_dpll_enable, - .disable = &omap3_noncore_dpll_disable, - .round_rate = &omap2_dpll_round_rate, + .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, .recalc = &omap3_dpll_recalc, }; @@ -643,7 +584,7 @@ static struct clk omap_96m_alwon_fck = { .parent = &dpll4_m2x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK, .clksel = omap_96m_alwon_fck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -669,7 +610,7 @@ static struct clk cm_96m_fck = { .parent = &dpll4_m2x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK, .clksel = cm_96m_fck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -711,7 +652,7 @@ static struct clk virt_omap_54m_fck = { .parent = &dpll4_m3x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK, .clksel = virt_omap_54m_fck_clksel, .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | PARENT_CONTROLS_CLOCK, @@ -863,33 +804,23 @@ static struct clk emu_per_alwon_ck = { /* Supplies 120MHz clock, USIM source clock */ /* Type: DPLL */ /* 3430ES2 only */ -static struct dpll_data dpll5_dd = { +static const struct dpll_data dpll5_dd = { .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4), .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK, .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, .control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2), .enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK, - .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), .auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT, .recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT, .recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT, - .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL), - .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK, - .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), - .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT, - .max_multiplier = OMAP3_MAX_DPLL_MULT, - .max_divider = OMAP3_MAX_DPLL_DIV, - .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; static struct clk dpll5_ck = { .name = "dpll5_ck", .parent = &sys_ck, .dpll_data = &dpll5_dd, - .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES, - .enable = &omap3_noncore_dpll_enable, - .disable = &omap3_noncore_dpll_disable, - .round_rate = &omap2_dpll_round_rate, + .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES | + ALWAYS_ENABLED, .recalc = &omap3_dpll_recalc, }; @@ -1434,8 +1365,7 @@ static const struct clksel mcbsp_15_clksel[] = { }; static struct clk mcbsp5_fck = { - .name = "mcbsp_fck", - .id = 5, + .name = "mcbsp5_fck", .init = &omap2_init_clksel_parent, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, @@ -1447,8 +1377,7 @@ static struct clk mcbsp5_fck = { }; static struct clk mcbsp1_fck = { - .name = "mcbsp_fck", - .id = 1, + .name = "mcbsp1_fck", .init = &omap2_init_clksel_parent, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, @@ -1860,8 +1789,7 @@ static struct clk gpt10_ick = { }; static struct clk mcbsp5_ick = { - .name = "mcbsp_ick", - .id = 5, + .name = "mcbsp5_ick", .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, @@ -1870,8 +1798,7 @@ static struct clk mcbsp5_ick = { }; static struct clk mcbsp1_ick = { - .name = "mcbsp_ick", - .id = 1, + .name = "mcbsp1_ick", .parent = &core_l4_ick, .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, @@ -2008,7 +1935,7 @@ static struct clk dss1_alwon_fck = { .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_DSS1_SHIFT, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK, .clksel = dss1_alwon_fck_clksel, .flags = CLOCK_IN_OMAP343X, .recalc = &omap2_clksel_recalc, @@ -2064,7 +1991,7 @@ static struct clk cam_mclk = { .parent = &dpll4_m5x2_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), - .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .clksel_mask = OMAP3430_ST_PERIPH_CLK, .clksel = cam_mclk_clksel, .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_CAM_SHIFT, @@ -2614,8 +2541,7 @@ static struct clk gpt2_ick = { }; static struct clk mcbsp2_ick = { - .name = "mcbsp_ick", - .id = 2, + .name = "mcbsp2_ick", .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, @@ -2624,8 +2550,7 @@ static struct clk mcbsp2_ick = { }; static struct clk mcbsp3_ick = { - .name = "mcbsp_ick", - .id = 3, + .name = "mcbsp3_ick", .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, @@ -2634,8 +2559,7 @@ static struct clk mcbsp3_ick = { }; static struct clk mcbsp4_ick = { - .name = "mcbsp_ick", - .id = 4, + .name = "mcbsp4_ick", .parent = &per_l4_ick, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, @@ -2650,8 +2574,7 @@ static const struct clksel mcbsp_234_clksel[] = { }; static struct clk mcbsp2_fck = { - .name = "mcbsp_fck", - .id = 2, + .name = "mcbsp2_fck", .init = &omap2_init_clksel_parent, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, @@ -2663,8 +2586,7 @@ static struct clk mcbsp2_fck = { }; static struct clk mcbsp3_fck = { - .name = "mcbsp_fck", - .id = 3, + .name = "mcbsp3_fck", .init = &omap2_init_clksel_parent, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, @@ -2676,8 +2598,7 @@ static struct clk mcbsp3_fck = { }; static struct clk mcbsp4_fck = { - .name = "mcbsp_fck", - .id = 4, + .name = "mcbsp4_fck", .init = &omap2_init_clksel_parent, .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, diff --git a/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h b/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h index ee4c0ca1a708..3c38395f6442 100644 --- a/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/trunk/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -72,8 +72,7 @@ #define OMAP3430_ST_IVA2 (1 << 0) /* CM_IDLEST_PLL_IVA2 */ -#define OMAP3430_ST_IVA2_CLK_SHIFT 0 -#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0) +#define OMAP3430_ST_IVA2_CLK (1 << 0) /* CM_AUTOIDLE_PLL_IVA2 */ #define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0 @@ -116,7 +115,10 @@ #define OMAP3430_ST_MPU (1 << 0) /* CM_IDLEST_PLL_MPU */ -#define OMAP3430_ST_MPU_CLK_SHIFT 0 +#define OMAP3430_ST_MPU_CLK (1 << 0) +#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0) + +/* CM_IDLEST_PLL_MPU */ #define OMAP3430_ST_MPU_CLK_MASK (1 << 0) /* CM_AUTOIDLE_PLL_MPU */ @@ -406,10 +408,8 @@ #define OMAP3430_ST_12M_CLK (1 << 4) #define OMAP3430_ST_48M_CLK (1 << 3) #define OMAP3430_ST_96M_CLK (1 << 2) -#define OMAP3430_ST_PERIPH_CLK_SHIFT 1 -#define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1) -#define OMAP3430_ST_CORE_CLK_SHIFT 0 -#define OMAP3430_ST_CORE_CLK_MASK (1 << 0) +#define OMAP3430_ST_PERIPH_CLK (1 << 1) +#define OMAP3430_ST_CORE_CLK (1 << 0) /* CM_IDLEST2_CKGEN */ #define OMAP3430ES2_ST_120M_CLK_SHIFT 1 @@ -423,10 +423,6 @@ #define OMAP3430_AUTO_CORE_DPLL_SHIFT 0 #define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0) -/* CM_AUTOIDLE2_PLL */ -#define OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT 0 -#define OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK (0x7 << 0) - /* CM_CLKSEL1_PLL */ /* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */ #define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27 diff --git a/trunk/arch/arm/mach-omap2/cm.h b/trunk/arch/arm/mach-omap2/cm.h index 87a44c715aa4..8489f3029fed 100644 --- a/trunk/arch/arm/mach-omap2/cm.h +++ b/trunk/arch/arm/mach-omap2/cm.h @@ -81,7 +81,6 @@ #define OMAP3430ES2_CM_FCLKEN3 0x0008 #define OMAP3430_CM_IDLEST_PLL CM_IDLEST2 #define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2 -#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2 #define OMAP3430_CM_CLKSEL1 CM_CLKSEL #define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL #define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2 @@ -97,21 +96,15 @@ /* Clock management domain register get/set */ #ifndef __ASSEMBLER__ - -extern u32 cm_read_mod_reg(s16 module, u16 idx); -extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); -extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); - -static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) +static inline void cm_write_mod_reg(u32 val, s16 module, s16 idx) { - return cm_rmw_mod_reg_bits(bits, bits, module, idx); + __raw_writel(val, OMAP_CM_REGADDR(module, idx)); } -static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) +static inline u32 cm_read_mod_reg(s16 module, s16 idx) { - return cm_rmw_mod_reg_bits(bits, 0x0, module, idx); + return __raw_readl(OMAP_CM_REGADDR(module, idx)); } - #endif /* CM register bits shared between 24XX and 3430 */ diff --git a/trunk/arch/arm/mach-omap2/control.c b/trunk/arch/arm/mach-omap2/control.c index 51f70300996f..a5d86a49c213 100644 --- a/trunk/arch/arm/mach-omap2/control.c +++ b/trunk/arch/arm/mach-omap2/control.c @@ -13,21 +13,22 @@ #undef DEBUG #include -#include -#include +#include + #include -static void __iomem *omap2_ctrl_base; +static u32 omap2_ctrl_base; -#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg)) +#define OMAP_CTRL_REGADDR(reg) (void __iomem *)IO_ADDRESS(omap2_ctrl_base \ + + (reg)) -void __init omap2_set_globals_control(struct omap_globals *omap2_globals) +void omap_ctrl_base_set(u32 base) { - omap2_ctrl_base = omap2_globals->ctrl; + omap2_ctrl_base = base; } -void __iomem *omap_ctrl_base_get(void) +u32 omap_ctrl_base_get(void) { return omap2_ctrl_base; } @@ -49,16 +50,25 @@ u32 omap_ctrl_readl(u16 offset) void omap_ctrl_writeb(u8 val, u16 offset) { + pr_debug("omap_ctrl_writeb: writing 0x%0x to 0x%0x\n", val, + (u32)OMAP_CTRL_REGADDR(offset)); + __raw_writeb(val, OMAP_CTRL_REGADDR(offset)); } void omap_ctrl_writew(u16 val, u16 offset) { + pr_debug("omap_ctrl_writew: writing 0x%0x to 0x%0x\n", val, + (u32)OMAP_CTRL_REGADDR(offset)); + __raw_writew(val, OMAP_CTRL_REGADDR(offset)); } void omap_ctrl_writel(u32 val, u16 offset) { + pr_debug("omap_ctrl_writel: writing 0x%0x to 0x%0x\n", val, + (u32)OMAP_CTRL_REGADDR(offset)); + __raw_writel(val, OMAP_CTRL_REGADDR(offset)); } diff --git a/trunk/arch/arm/mach-omap2/gpmc.c b/trunk/arch/arm/mach-omap2/gpmc.c index dbf68dc50ae2..02cede295e89 100644 --- a/trunk/arch/arm/mach-omap2/gpmc.c +++ b/trunk/arch/arm/mach-omap2/gpmc.c @@ -42,7 +42,7 @@ #define GPMC_STATUS 0x54 #define GPMC_PREFETCH_CONFIG1 0x1e0 #define GPMC_PREFETCH_CONFIG2 0x1e4 -#define GPMC_PREFETCH_CONTROL 0x1ec +#define GPMC_PREFETCH_CONTROL 0x1e8 #define GPMC_PREFETCH_STATUS 0x1f0 #define GPMC_ECC_CONFIG 0x1f4 #define GPMC_ECC_CONTROL 0x1f8 diff --git a/trunk/arch/arm/mach-omap2/id.c b/trunk/arch/arm/mach-omap2/id.c index dff4b16cead6..4dfd878d7968 100644 --- a/trunk/arch/arm/mach-omap2/id.c +++ b/trunk/arch/arm/mach-omap2/id.c @@ -17,23 +17,16 @@ #include -#include -#include - #if defined(CONFIG_ARCH_OMAP2420) -#define TAP_BASE io_p2v(0x48014000) -#elif defined(CONFIG_ARCH_OMAP2430) -#define TAP_BASE io_p2v(0x4900A000) -#elif defined(CONFIG_ARCH_OMAP34XX) -#define TAP_BASE io_p2v(0x4830A000) +#define OMAP24XX_TAP_BASE io_p2v(0x48014000) +#endif + +#if defined(CONFIG_ARCH_OMAP2430) +#define OMAP24XX_TAP_BASE io_p2v(0x4900A000) #endif #define OMAP_TAP_IDCODE 0x0204 -#if defined(CONFIG_ARCH_OMAP34XX) -#define OMAP_TAP_PROD_ID 0x0210 -#else #define OMAP_TAP_PROD_ID 0x0208 -#endif #define OMAP_TAP_DIE_ID_0 0x0218 #define OMAP_TAP_DIE_ID_1 0x021C @@ -63,134 +56,9 @@ static struct omap_id omap_ids[] __initdata = { { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, }; -static struct omap_chip_id omap_chip; - -/** - * omap_chip_is - test whether currently running OMAP matches a chip type - * @oc: omap_chip_t to test against - * - * Test whether the currently-running OMAP chip matches the supplied - * chip type 'oc'. Returns 1 upon a match; 0 upon failure. - */ -int omap_chip_is(struct omap_chip_id oci) -{ - return (oci.oc & omap_chip.oc) ? 1 : 0; -} -EXPORT_SYMBOL(omap_chip_is); - static u32 __init read_tap_reg(int reg) { - unsigned int regval = 0; - u32 cpuid; - - /* Reading the IDCODE register on 3430 ES1 results in a - * data abort as the register is not exposed on the OCP - * Hence reading the Cortex Rev - */ - cpuid = read_cpuid(CPUID_ID); - - /* If the processor type is Cortex-A8 and the revision is 0x0 - * it means its Cortex r0p0 which is 3430 ES1 - */ - if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) { - switch (reg) { - case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break; - /* Making DevType as 0xF in ES1 to differ from ES2 */ - case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break; - case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break; - case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break; - case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break; - case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break; - } - } else - regval = __raw_readl(TAP_BASE + reg); - - return regval; - -} - -/* - * _set_system_rev - set the system_rev global based on current OMAP chip type - * - * Set the system_rev global. This is primarily used by the cpu_is_omapxxxx() - * macros. - */ -static void __init _set_system_rev(u32 type, u8 rev) -{ - u32 i, ctrl_status; - - /* - * system_rev encoding is as follows - * system_rev & 0xff000000 -> Omap Class (24xx/34xx) - * system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) - * system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) - * system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) - * system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) - * system_rev & 0x000000c0 -> IDCODE revision[6:7] - * system_rev & 0x0000003f -> sys_boot[0:5] - */ - /* Embedding the ES revision info in type field */ - system_rev = type; - /* Also add IDCODE revision info only two lower bits */ - system_rev |= ((rev & 0x3) << 6); - - /* Add in the device type and sys_boot fields (see above) */ - if (cpu_is_omap24xx()) { - i = OMAP24XX_CONTROL_STATUS; - } else if (cpu_is_omap343x()) { - i = OMAP343X_CONTROL_STATUS; - } else { - printk(KERN_ERR "id: unknown CPU type\n"); - BUG(); - } - ctrl_status = omap_ctrl_readl(i); - system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | - OMAP2_SYSBOOT_4_MASK | - OMAP2_SYSBOOT_3_MASK | - OMAP2_SYSBOOT_2_MASK | - OMAP2_SYSBOOT_1_MASK | - OMAP2_SYSBOOT_0_MASK)); - system_rev |= (ctrl_status & OMAP2_DEVICETYPE_MASK); -} - - -/* - * _set_omap_chip - set the omap_chip global based on OMAP chip type - * - * Build the omap_chip bits. This variable is used by powerdomain and - * clockdomain code to indicate whether structures are applicable for - * the current OMAP chip type by ANDing it against a 'platform' bitfield - * in the structure. - */ -static void __init _set_omap_chip(void) -{ - if (cpu_is_omap343x()) { - - omap_chip.oc = CHIP_IS_OMAP3430; - if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) - omap_chip.oc |= CHIP_IS_OMAP3430ES1; - else if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) - omap_chip.oc |= CHIP_IS_OMAP3430ES2; - - } else if (cpu_is_omap243x()) { - - /* Currently only supports 2430ES2.1 and 2430-all */ - omap_chip.oc |= CHIP_IS_OMAP2430; - - } else if (cpu_is_omap242x()) { - - /* Currently only supports 2420ES2.1.1 and 2420-all */ - omap_chip.oc |= CHIP_IS_OMAP2420; - - } else { - - /* Current CPU not supported by this code. */ - printk(KERN_WARNING "OMAP chip type code does not yet support " - "this CPU type.\n"); - WARN_ON(1); - - } - + return __raw_readl(OMAP24XX_TAP_BASE + reg); } void __init omap2_check_revision(void) @@ -208,31 +76,21 @@ void __init omap2_check_revision(void) rev = (idcode >> 28) & 0x0f; dev_type = (prod_id >> 16) & 0x0f; - pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", - idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); - pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_0)); - pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", - read_tap_reg(OMAP_TAP_DIE_ID_1), - (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); - pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_2)); - pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", - read_tap_reg(OMAP_TAP_DIE_ID_3)); - pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", - prod_id, dev_type); - - /* - * Detection for 34xx ES2.0 and above can be done with just - * hawkeye and rev. See TRM 1.5.2 Device Identification. - * Note that rev cannot be used directly as ES1.0 uses value 0. - */ - if (hawkeye == 0xb7ae) { - system_rev = 0x34300000 | ((1 + rev) << 12); - pr_info("OMAP%04x ES2.%i\n", system_rev >> 16, rev); - _set_omap_chip(); - return; - } +#ifdef DEBUG + printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", + idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); + printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n", + read_tap_reg(OMAP_TAP_DIE_ID_0)); + printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", + read_tap_reg(OMAP_TAP_DIE_ID_1), + (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); + printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n", + read_tap_reg(OMAP_TAP_DIE_ID_2)); + printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n", + read_tap_reg(OMAP_TAP_DIE_ID_3)); + printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", + prod_id, dev_type); +#endif /* Check hawkeye ids */ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { @@ -256,15 +114,16 @@ void __init omap2_check_revision(void) omap_ids[i].type >> 16); j = i; } + system_rev = omap_ids[j].type; - _set_system_rev(omap_ids[j].type, rev); + system_rev |= rev << 8; - _set_omap_chip(); + /* Add the cpu class info (24xx) */ + system_rev |= 0x24; pr_info("OMAP%04x", system_rev >> 16); if ((system_rev >> 8) & 0x0f) - pr_info("ES%x", (system_rev >> 12) & 0xf); - pr_info("\n"); - + printk("%x", (system_rev >> 8) & 0x0f); + printk("\n"); } diff --git a/trunk/arch/arm/mach-omap2/mcbsp.c b/trunk/arch/arm/mach-omap2/mcbsp.c deleted file mode 100644 index 17cf199d1130..000000000000 --- a/trunk/arch/arm/mach-omap2/mcbsp.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/mcbsp.c - * - * Copyright (C) 2008 Instituto Nokia de Tecnologia - * Contact: Eduardo Valentin - * - * 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. - * - * Multichannel mode not supported. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -struct mcbsp_internal_clk { - struct clk clk; - struct clk **childs; - int n_childs; -}; - -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) -static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) -{ - const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; - int i; - - mclk->n_childs = ARRAY_SIZE(clk_names); - mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), - GFP_KERNEL); - - for (i = 0; i < mclk->n_childs; i++) { - /* We fake a platform device to get correct device id */ - struct platform_device pdev; - - pdev.dev.bus = &platform_bus_type; - pdev.id = mclk->clk.id; - mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); - if (IS_ERR(mclk->childs[i])) - printk(KERN_ERR "Could not get clock %s (%d).\n", - clk_names[i], mclk->clk.id); - } -} - -static int omap_mcbsp_clk_enable(struct clk *clk) -{ - struct mcbsp_internal_clk *mclk = container_of(clk, - struct mcbsp_internal_clk, clk); - int i; - - for (i = 0; i < mclk->n_childs; i++) - clk_enable(mclk->childs[i]); - return 0; -} - -static void omap_mcbsp_clk_disable(struct clk *clk) -{ - struct mcbsp_internal_clk *mclk = container_of(clk, - struct mcbsp_internal_clk, clk); - int i; - - for (i = 0; i < mclk->n_childs; i++) - clk_disable(mclk->childs[i]); -} - -static struct mcbsp_internal_clk omap_mcbsp_clks[] = { - { - .clk = { - .name = "mcbsp_clk", - .id = 1, - .enable = omap_mcbsp_clk_enable, - .disable = omap_mcbsp_clk_disable, - }, - }, - { - .clk = { - .name = "mcbsp_clk", - .id = 2, - .enable = omap_mcbsp_clk_enable, - .disable = omap_mcbsp_clk_disable, - }, - }, -}; - -#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) -#else -#define omap_mcbsp_clks_size 0 -static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; -static inline void omap_mcbsp_clk_init(struct clk *clk) -{ } -#endif - -static void omap2_mcbsp2_mux_setup(void) -{ - omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); - omap_cfg_reg(R14_24XX_MCBSP2_FSX); - omap_cfg_reg(W15_24XX_MCBSP2_DR); - omap_cfg_reg(V15_24XX_MCBSP2_DX); - omap_cfg_reg(V14_24XX_GPIO117); - /* - * TODO: Need to add MUX settings for OMAP 2430 SDP - */ -} - -static void omap2_mcbsp_request(unsigned int id) -{ - if (cpu_is_omap2420() && (id == OMAP_MCBSP2)) - omap2_mcbsp2_mux_setup(); -} - -static int omap2_mcbsp_check(unsigned int id) -{ - if (id > OMAP_MAX_MCBSP_COUNT - 1) { - printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); - return -ENODEV; - } - return 0; -} - -static struct omap_mcbsp_ops omap2_mcbsp_ops = { - .request = omap2_mcbsp_request, - .check = omap2_mcbsp_check, -}; - -#ifdef CONFIG_ARCH_OMAP24XX -static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = { - { - .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, -}; -#define OMAP24XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap24xx_mcbsp_pdata) -#else -#define omap24xx_mcbsp_pdata NULL -#define OMAP24XX_MCBSP_PDATA_SZ 0 -#endif - -#ifdef CONFIG_ARCH_OMAP34XX -static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { - { - .virt_base = IO_ADDRESS(OMAP34XX_MCBSP1_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, - .rx_irq = INT_24XX_MCBSP1_IRQ_RX, - .tx_irq = INT_24XX_MCBSP1_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, - { - .virt_base = IO_ADDRESS(OMAP34XX_MCBSP2_BASE), - .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, - .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, - .rx_irq = INT_24XX_MCBSP2_IRQ_RX, - .tx_irq = INT_24XX_MCBSP2_IRQ_TX, - .ops = &omap2_mcbsp_ops, - .clk_name = "mcbsp_clk", - }, -}; -#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) -#else -#define omap34xx_mcbsp_pdata NULL -#define OMAP34XX_MCBSP_PDATA_SZ 0 -#endif - -int __init omap2_mcbsp_init(void) -{ - int i; - - for (i = 0; i < omap_mcbsp_clks_size; i++) { - /* Once we call clk_get inside init, we do not register it */ - omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); - clk_register(&omap_mcbsp_clks[i].clk); - } - - if (cpu_is_omap24xx()) - omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata, - OMAP24XX_MCBSP_PDATA_SZ); - - if (cpu_is_omap34xx()) - omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, - OMAP34XX_MCBSP_PDATA_SZ); - - return omap_mcbsp_init(); -} -arch_initcall(omap2_mcbsp_init); diff --git a/trunk/arch/arm/mach-omap2/memory.c b/trunk/arch/arm/mach-omap2/memory.c index 73cadb2c75cf..12479081881a 100644 --- a/trunk/arch/arm/mach-omap2/memory.c +++ b/trunk/arch/arm/mach-omap2/memory.c @@ -24,7 +24,6 @@ #include -#include #include #include @@ -33,8 +32,8 @@ #include "memory.h" #include "sdrc.h" -void __iomem *omap2_sdrc_base; -void __iomem *omap2_sms_base; +unsigned long omap2_sdrc_base; +unsigned long omap2_sms_base; static struct memory_timings mem_timings; static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2; @@ -155,12 +154,6 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode) mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); } -void __init omap2_set_globals_memory(struct omap_globals *omap2_globals) -{ - omap2_sdrc_base = omap2_globals->sdrc; - omap2_sms_base = omap2_globals->sms; -} - /* turn on smart idle modes for SDRAM scheduler and controller */ void __init omap2_init_memory(void) { diff --git a/trunk/arch/arm/mach-omap2/mux.c b/trunk/arch/arm/mach-omap2/mux.c index 8f98b20f30a1..930770012a75 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -236,7 +236,7 @@ void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u8 reg) warn = (orig != reg); if (debug || warn) printk(KERN_WARNING - "MUX: setup %s (0x%p): 0x%04x -> 0x%04x\n", + "MUX: setup %s (0x%08x): 0x%02x -> 0x%02x\n", cfg->name, omap_ctrl_base_get() + cfg->mux_reg, orig, reg); } diff --git a/trunk/arch/arm/mach-omap2/prcm-common.h b/trunk/arch/arm/mach-omap2/prcm-common.h index 54c32f482131..cacb34086e35 100644 --- a/trunk/arch/arm/mach-omap2/prcm-common.h +++ b/trunk/arch/arm/mach-omap2/prcm-common.h @@ -32,7 +32,6 @@ /* Chip-specific module offsets */ -#define OMAP24XX_GR_MOD OCP_MOD #define OMAP24XX_DSP_MOD 0x800 #define OMAP2430_MDM_MOD 0xc00 diff --git a/trunk/arch/arm/mach-omap2/prcm.c b/trunk/arch/arm/mach-omap2/prcm.c index fd92a80f38f2..b12f423b8595 100644 --- a/trunk/arch/arm/mach-omap2/prcm.c +++ b/trunk/arch/arm/mach-omap2/prcm.c @@ -16,21 +16,16 @@ #include #include #include -#include -#include -#include +#include -#include "clock.h" #include "prm.h" #include "prm-regbits-24xx.h" -static void __iomem *prm_base; -static void __iomem *cm_base; +extern void omap2_clk_prepare_for_reboot(void); u32 omap_prcm_get_reset_sources(void) { - /* XXX This presumably needs modification for 34XX */ return prm_read_mod_reg(WKUP_MOD, RM_RSTST) & 0x7f; } EXPORT_SYMBOL(omap_prcm_get_reset_sources); @@ -38,90 +33,11 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources); /* Resets clock rates and reboots the system. Only called from system.h */ void omap_prcm_arch_reset(char mode) { - s16 prcm_offs; + u32 wkup; omap2_clk_prepare_for_reboot(); - if (cpu_is_omap24xx()) - prcm_offs = WKUP_MOD; - else if (cpu_is_omap34xx()) - prcm_offs = OMAP3430_GR_MOD; - else - WARN_ON(1); - - prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL); -} - -static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg) -{ - BUG_ON(!base); - return __raw_readl(base + module + reg); -} - -static inline void __omap_prcm_write(u32 value, void __iomem *base, - s16 module, u16 reg) -{ - BUG_ON(!base); - __raw_writel(value, base + module + reg); -} - -/* Read a register in a PRM module */ -u32 prm_read_mod_reg(s16 module, u16 idx) -{ - return __omap_prcm_read(prm_base, module, idx); -} -EXPORT_SYMBOL(prm_read_mod_reg); - -/* Write into a register in a PRM module */ -void prm_write_mod_reg(u32 val, s16 module, u16 idx) -{ - __omap_prcm_write(val, prm_base, module, idx); -} -EXPORT_SYMBOL(prm_write_mod_reg); - -/* Read-modify-write a register in a PRM module. Caller must lock */ -u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) -{ - u32 v; - - v = prm_read_mod_reg(module, idx); - v &= ~mask; - v |= bits; - prm_write_mod_reg(v, module, idx); - - return v; -} -EXPORT_SYMBOL(prm_rmw_mod_reg_bits); - -/* Read a register in a CM module */ -u32 cm_read_mod_reg(s16 module, u16 idx) -{ - return __omap_prcm_read(cm_base, module, idx); -} -EXPORT_SYMBOL(cm_read_mod_reg); - -/* Write into a register in a CM module */ -void cm_write_mod_reg(u32 val, s16 module, u16 idx) -{ - __omap_prcm_write(val, cm_base, module, idx); -} -EXPORT_SYMBOL(cm_write_mod_reg); - -/* Read-modify-write a register in a CM module. Caller must lock */ -u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) -{ - u32 v; - - v = cm_read_mod_reg(module, idx); - v &= ~mask; - v |= bits; - cm_write_mod_reg(v, module, idx); - - return v; -} -EXPORT_SYMBOL(cm_rmw_mod_reg_bits); - -void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) -{ - prm_base = omap2_globals->prm; - cm_base = omap2_globals->cm; + if (cpu_is_omap24xx()) { + wkup = prm_read_mod_reg(WKUP_MOD, RM_RSTCTRL) | OMAP_RST_DPLL3; + prm_write_mod_reg(wkup, WKUP_MOD, RM_RSTCTRL); + } } diff --git a/trunk/arch/arm/mach-omap2/prm.h b/trunk/arch/arm/mach-omap2/prm.h index bbf41fc8e9a9..618f8111658a 100644 --- a/trunk/arch/arm/mach-omap2/prm.h +++ b/trunk/arch/arm/mach-omap2/prm.h @@ -38,29 +38,13 @@ * */ -/* Global 24xx registers in GR_MOD (Same as OCP_MOD for 24xx) */ -#define OMAP24XX_PRCM_VOLTCTRL_OFFSET 0x0050 -#define OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET 0x0080 - -/* 242x GR_MOD registers, use these only for assembly code */ -#define OMAP242X_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_VOLTCTRL_OFFSET) -#define OMAP242X_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) - -/* 243x GR_MOD registers, use these only for assembly code */ -#define OMAP243X_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_VOLTCTRL_OFFSET) -#define OMAP243X_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ - OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) - -/* These will disappear */ #define OMAP24XX_PRCM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0000) #define OMAP24XX_PRCM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0010) #define OMAP24XX_PRCM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) #define OMAP24XX_PRCM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) +#define OMAP24XX_PRCM_VOLTCTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0050) #define OMAP24XX_PRCM_VOLTST OMAP_PRM_REGADDR(OCP_MOD, 0x0054) #define OMAP24XX_PRCM_CLKSRC_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0060) #define OMAP24XX_PRCM_CLKOUT_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0070) @@ -166,19 +150,15 @@ #ifndef __ASSEMBLER__ /* Power/reset management domain register get/set */ -extern u32 prm_read_mod_reg(s16 module, u16 idx); -extern void prm_write_mod_reg(u32 val, s16 module, u16 idx); -extern u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); -/* Read-modify-write bits in a PRM register (by domain) */ -static inline u32 prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) +static inline void prm_write_mod_reg(u32 val, s16 module, s16 idx) { - return prm_rmw_mod_reg_bits(bits, bits, module, idx); + __raw_writel(val, OMAP_PRM_REGADDR(module, idx)); } -static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) +static inline u32 prm_read_mod_reg(s16 module, s16 idx) { - return prm_rmw_mod_reg_bits(bits, 0x0, module, idx); + return __raw_readl(OMAP_PRM_REGADDR(module, idx)); } #endif diff --git a/trunk/arch/arm/mach-omap2/sdrc.h b/trunk/arch/arm/mach-omap2/sdrc.h index 1b1fe4f6e030..d7f23bc9550a 100644 --- a/trunk/arch/arm/mach-omap2/sdrc.h +++ b/trunk/arch/arm/mach-omap2/sdrc.h @@ -18,11 +18,13 @@ #include #ifndef __ASSEMBLER__ -extern void __iomem *omap2_sdrc_base; -extern void __iomem *omap2_sms_base; +extern unsigned long omap2_sdrc_base; +extern unsigned long omap2_sms_base; -#define OMAP_SDRC_REGADDR(reg) (omap2_sdrc_base + (reg)) -#define OMAP_SMS_REGADDR(reg) (omap2_sms_base + (reg)) +#define OMAP_SDRC_REGADDR(reg) \ + (void __iomem *)IO_ADDRESS(omap2_sdrc_base + (reg)) +#define OMAP_SMS_REGADDR(reg) \ + (void __iomem *)IO_ADDRESS(omap2_sms_base + (reg)) /* SDRC global register get/set */ diff --git a/trunk/arch/arm/mach-omap2/sram242x.S b/trunk/arch/arm/mach-omap2/sram-fn.S similarity index 80% rename from trunk/arch/arm/mach-omap2/sram242x.S rename to trunk/arch/arm/mach-omap2/sram-fn.S index 4c274510f3e9..4a9e49140716 100644 --- a/trunk/arch/arm/mach-omap2/sram242x.S +++ b/trunk/arch/arm/mach-omap2/sram-fn.S @@ -1,5 +1,5 @@ /* - * linux/arch/arm/mach-omap2/sram242x.S + * linux/arch/arm/mach-omap2/sram-fn.S * * Omap2 specific functions that need to be run in internal SRAM * @@ -27,20 +27,22 @@ #include #include +#include "sdrc.h" #include "prm.h" #include "cm.h" -#include "sdrc.h" + +#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) .text -ENTRY(omap242x_sram_ddr_init) +ENTRY(sram_ddr_init) stmfd sp!, {r0 - r12, lr} @ save registers on stack mov r12, r2 @ capture CS1 vs CS0 mov r8, r3 @ capture force parameter /* frequency shift down */ - ldr r2, omap242x_sdi_cm_clksel2_pll @ get address of dpllout reg + ldr r2, cm_clksel2_pll @ get address of dpllout reg mov r3, #0x1 @ value for 1x operation str r3, [r2] @ go to L1-freq operation @@ -49,7 +51,7 @@ ENTRY(omap242x_sram_ddr_init) bl voltage_shift @ go drop voltage /* dll lock mode */ - ldr r11, omap242x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl + ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl ldr r10, [r11] @ get current val cmp r12, #0x1 @ cs1 base (2422 es2.05/1) addeq r11, r11, #0x8 @ if cs1 base, move to DLLB @@ -100,7 +102,7 @@ i_dll_delay: * wait for it to finish, use 32k sync counter, 1tick=31uS. */ voltage_shift: - ldr r4, omap242x_sdi_prcm_voltctrl @ get addr of volt ctrl. + ldr r4, prcm_voltctrl @ get addr of volt ctrl. ldr r5, [r4] @ get value. ldr r6, prcm_mask_val @ get value of mask and r5, r5, r6 @ apply mask to clear bits @@ -110,7 +112,7 @@ voltage_shift: orr r5, r5, r3 @ build value for force str r5, [r4] @ Force transition to L1 - ldr r3, omap242x_sdi_timer_32ksynct_cr @ get addr of counter + ldr r3, timer_32ksynct_cr @ get addr of counter ldr r5, [r3] @ get value add r5, r5, #0x3 @ give it at most 93uS volt_delay: @@ -119,31 +121,32 @@ volt_delay: bhi volt_delay @ not yet->branch mov pc, lr @ back to caller. -omap242x_sdi_cm_clksel2_pll: +/* relative load constants */ +cm_clksel2_pll: .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) -omap242x_sdi_sdrc_dlla_ctrl: +sdrc_dlla_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) -omap242x_sdi_prcm_voltctrl: - .word OMAP242X_PRCM_VOLTCTRL +prcm_voltctrl: + .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50) prcm_mask_val: .word 0xFFFF3FFC -omap242x_sdi_timer_32ksynct_cr: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) -ENTRY(omap242x_sram_ddr_init_sz) - .word . - omap242x_sram_ddr_init +timer_32ksynct_cr: + .word TIMER_32KSYNCT_CR_V +ENTRY(sram_ddr_init_sz) + .word . - sram_ddr_init /* * Reprograms memory timings. * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 */ -ENTRY(omap242x_sram_reprogram_sdrc) +ENTRY(sram_reprogram_sdrc) stmfd sp!, {r0 - r10, lr} @ save registers on stack mov r3, #0x0 @ clear for mrc call mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR nop nop - ldr r6, omap242x_srs_sdrc_rfr_ctrl @ get addr of refresh reg + ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg ldr r5, [r6] @ get value mov r5, r5, lsr #8 @ isolate rfr field and drop burst @@ -157,7 +160,7 @@ ENTRY(omap242x_sram_reprogram_sdrc) movne r5, r5, lsl #1 @ mult by 2 if to full mov r5, r5, lsl #8 @ put rfr field back into place add r5, r5, #0x1 @ turn on burst of 1 - ldr r4, omap242x_srs_cm_clksel2_pll @ get address of out reg + ldr r4, ddr_cm_clksel2_pll @ get address of out reg ldr r3, [r4] @ get curr value orr r3, r3, #0x3 bic r3, r3, #0x3 @ clear lower bits @@ -178,7 +181,7 @@ ENTRY(omap242x_sram_reprogram_sdrc) bne freq_out @ leave if SDR, no DLL function /* With DDR, we need to take care of the DLL for the frequency change */ - ldr r2, omap242x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl + ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl str r1, [r2] @ write out new SDRC_DLLA_CTRL add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL str r1, [r2] @ commit to SDRC_DLLB_CTRL @@ -194,7 +197,7 @@ freq_out: * wait for it to finish, use 32k sync counter, 1tick=31uS. */ voltage_shift_c: - ldr r10, omap242x_srs_prcm_voltctrl @ get addr of volt ctrl + ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl ldr r8, [r10] @ get value ldr r7, ddr_prcm_mask_val @ get value of mask and r8, r8, r7 @ apply mask to clear bits @@ -204,7 +207,7 @@ voltage_shift_c: orr r8, r8, r7 @ build value for force str r8, [r10] @ Force transition to L1 - ldr r10, omap242x_srs_timer_32ksynct @ get addr of counter + ldr r10, ddr_timer_32ksynct @ get addr of counter ldr r8, [r10] @ get value add r8, r8, #0x2 @ give it at most 62uS (min 31+) volt_delay_c: @@ -213,39 +216,39 @@ volt_delay_c: bhi volt_delay_c @ not yet->branch mov pc, lr @ back to caller -omap242x_srs_cm_clksel2_pll: +ddr_cm_clksel2_pll: .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) -omap242x_srs_sdrc_dlla_ctrl: +ddr_sdrc_dlla_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) -omap242x_srs_sdrc_rfr_ctrl: +ddr_sdrc_rfr_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) -omap242x_srs_prcm_voltctrl: - .word OMAP242X_PRCM_VOLTCTRL +ddr_prcm_voltctrl: + .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50) ddr_prcm_mask_val: .word 0xFFFF3FFC -omap242x_srs_timer_32ksynct: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) +ddr_timer_32ksynct: + .word TIMER_32KSYNCT_CR_V -ENTRY(omap242x_sram_reprogram_sdrc_sz) - .word . - omap242x_sram_reprogram_sdrc +ENTRY(sram_reprogram_sdrc_sz) + .word . - sram_reprogram_sdrc /* * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. */ -ENTRY(omap242x_sram_set_prcm) +ENTRY(sram_set_prcm) stmfd sp!, {r0-r12, lr} @ regs to stack adr r4, pbegin @ addr of preload start adr r8, pend @ addr of preload end mcrr p15, 1, r8, r4, c12 @ preload into icache pbegin: /* move into fast relock bypass */ - ldr r8, omap242x_ssp_pll_ctl @ get addr + ldr r8, pll_ctl @ get addr ldr r5, [r8] @ get val mvn r6, #0x3 @ clear mask and r5, r5, r6 @ clear field orr r7, r5, #0x2 @ fast relock val str r7, [r8] @ go to fast relock - ldr r4, omap242x_ssp_pll_stat @ addr of stat + ldr r4, pll_stat @ addr of stat block: /* wait for bypass */ ldr r8, [r4] @ stat value @@ -254,10 +257,10 @@ block: bne block @ loop if not /* set new dpll dividers _after_ in bypass */ - ldr r4, omap242x_ssp_pll_div @ get addr + ldr r4, pll_div @ get addr str r0, [r4] @ set dpll ctrl val - ldr r4, omap242x_ssp_set_config @ get addr + ldr r4, set_config @ get addr mov r8, #1 @ valid cfg msk str r8, [r4] @ make dividers take @@ -271,8 +274,8 @@ wait_a_bit: beq pend @ jump over dpll relock /* relock DPLL with new vals */ - ldr r5, omap242x_ssp_pll_stat @ get addr - ldr r4, omap242x_ssp_pll_ctl @ get addr + ldr r5, pll_stat @ get addr + ldr r4, pll_ctl @ get addr orr r8, r7, #0x3 @ val for lock dpll str r8, [r4] @ set val mov r0, #1000 @ dead spin a bit @@ -286,9 +289,9 @@ wait_lock: bne wait_lock @ wait if not pend: /* update memory timings & briefly lock dll */ - ldr r4, omap242x_ssp_sdrc_rfr @ get addr + ldr r4, sdrc_rfr @ get addr str r1, [r4] @ update refresh timing - ldr r11, omap242x_ssp_dlla_ctrl @ get addr of DLLA ctrl + ldr r11, dlla_ctrl @ get addr of DLLA ctrl ldr r10, [r11] @ get current val mvn r9, #0x4 @ mask to get clear bit2 and r10, r10, r9 @ clear bit2 for lock mode @@ -304,18 +307,18 @@ wait_dll_lock: nop ldmfd sp!, {r0-r12, pc} @ restore regs and return -omap242x_ssp_set_config: - .word OMAP242X_PRCM_CLKCFG_CTRL -omap242x_ssp_pll_ctl: - .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN) -omap242x_ssp_pll_stat: - .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST) -omap242x_ssp_pll_div: - .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL1) -omap242x_ssp_sdrc_rfr: +set_config: + .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x80) +pll_ctl: + .word OMAP2420_CM_REGADDR(PLL_MOD, CM_FCLKEN1) +pll_stat: + .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST1) +pll_div: + .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL) +sdrc_rfr: .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) -omap242x_ssp_dlla_ctrl: +dlla_ctrl: .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) -ENTRY(omap242x_sram_set_prcm_sz) - .word . - omap242x_sram_set_prcm +ENTRY(sram_set_prcm_sz) + .word . - sram_set_prcm diff --git a/trunk/arch/arm/mach-omap2/sram243x.S b/trunk/arch/arm/mach-omap2/sram243x.S deleted file mode 100644 index a3fa48dc08cd..000000000000 --- a/trunk/arch/arm/mach-omap2/sram243x.S +++ /dev/null @@ -1,321 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/sram243x.S - * - * Omap2 specific functions that need to be run in internal SRAM - * - * (C) Copyright 2004 - * Texas Instruments, - * Richard Woodruff - * - * 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 -#include -#include -#include - -#include "prm.h" -#include "cm.h" -#include "sdrc.h" - - .text - -ENTRY(omap243x_sram_ddr_init) - stmfd sp!, {r0 - r12, lr} @ save registers on stack - - mov r12, r2 @ capture CS1 vs CS0 - mov r8, r3 @ capture force parameter - - /* frequency shift down */ - ldr r2, omap243x_sdi_cm_clksel2_pll @ get address of dpllout reg - mov r3, #0x1 @ value for 1x operation - str r3, [r2] @ go to L1-freq operation - - /* voltage shift down */ - mov r9, #0x1 @ set up for L1 voltage call - bl voltage_shift @ go drop voltage - - /* dll lock mode */ - ldr r11, omap243x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl - ldr r10, [r11] @ get current val - cmp r12, #0x1 @ cs1 base (2422 es2.05/1) - addeq r11, r11, #0x8 @ if cs1 base, move to DLLB - mvn r9, #0x4 @ mask to get clear bit2 - and r10, r10, r9 @ clear bit2 for lock mode. - orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) - orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz - str r10, [r11] @ commit to DLLA_CTRL - bl i_dll_wait @ wait for dll to lock - - /* get dll value */ - add r11, r11, #0x4 @ get addr of status reg - ldr r10, [r11] @ get locked value - - /* voltage shift up */ - mov r9, #0x0 @ shift back to L0-voltage - bl voltage_shift @ go raise voltage - - /* frequency shift up */ - mov r3, #0x2 @ value for 2x operation - str r3, [r2] @ go to L0-freq operation - - /* reset entry mode for dllctrl */ - sub r11, r11, #0x4 @ move from status to ctrl - cmp r12, #0x1 @ normalize if cs1 based - subeq r11, r11, #0x8 @ possibly back to DLLA - cmp r8, #0x1 @ if forced unlock exit - orreq r1, r1, #0x4 @ make sure exit with unlocked value - str r1, [r11] @ restore DLLA_CTRL high value - add r11, r11, #0x8 @ move to DLLB_CTRL addr - str r1, [r11] @ set value DLLB_CTRL - bl i_dll_wait @ wait for possible lock - - /* set up for return, DDR should be good */ - str r10, [r0] @ write dll_status and return counter - ldmfd sp!, {r0 - r12, pc} @ restore regs and return - - /* ensure the DLL has relocked */ -i_dll_wait: - mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks -i_dll_delay: - subs r4, r4, #0x1 - bne i_dll_delay - mov pc, lr - - /* - * shift up or down voltage, use R9 as input to tell level. - * wait for it to finish, use 32k sync counter, 1tick=31uS. - */ -voltage_shift: - ldr r4, omap243x_sdi_prcm_voltctrl @ get addr of volt ctrl. - ldr r5, [r4] @ get value. - ldr r6, prcm_mask_val @ get value of mask - and r5, r5, r6 @ apply mask to clear bits - orr r5, r5, r9 @ bulld value for L0/L1-volt operation. - str r5, [r4] @ set up for change. - mov r3, #0x4000 @ get val for force - orr r5, r5, r3 @ build value for force - str r5, [r4] @ Force transition to L1 - - ldr r3, omap243x_sdi_timer_32ksynct_cr @ get addr of counter - ldr r5, [r3] @ get value - add r5, r5, #0x3 @ give it at most 93uS -volt_delay: - ldr r7, [r3] @ get timer value - cmp r5, r7 @ time up? - bhi volt_delay @ not yet->branch - mov pc, lr @ back to caller. - -omap243x_sdi_cm_clksel2_pll: - .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) -omap243x_sdi_sdrc_dlla_ctrl: - .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) -omap243x_sdi_prcm_voltctrl: - .word OMAP243X_PRCM_VOLTCTRL -prcm_mask_val: - .word 0xFFFF3FFC -omap243x_sdi_timer_32ksynct_cr: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) -ENTRY(omap243x_sram_ddr_init_sz) - .word . - omap243x_sram_ddr_init - -/* - * Reprograms memory timings. - * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] - * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 - */ -ENTRY(omap243x_sram_reprogram_sdrc) - stmfd sp!, {r0 - r10, lr} @ save registers on stack - mov r3, #0x0 @ clear for mrc call - mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR - nop - nop - ldr r6, omap243x_srs_sdrc_rfr_ctrl @ get addr of refresh reg - ldr r5, [r6] @ get value - mov r5, r5, lsr #8 @ isolate rfr field and drop burst - - cmp r0, #0x1 @ going to half speed? - movne r9, #0x0 @ if up set flag up for pre up, hi volt - - blne voltage_shift_c @ adjust voltage - - cmp r0, #0x1 @ going to half speed (post branch link) - moveq r5, r5, lsr #1 @ divide by 2 if to half - movne r5, r5, lsl #1 @ mult by 2 if to full - mov r5, r5, lsl #8 @ put rfr field back into place - add r5, r5, #0x1 @ turn on burst of 1 - ldr r4, omap243x_srs_cm_clksel2_pll @ get address of out reg - ldr r3, [r4] @ get curr value - orr r3, r3, #0x3 - bic r3, r3, #0x3 @ clear lower bits - orr r3, r3, r0 @ new state value - str r3, [r4] @ set new state (pll/x, x=1 or 2) - nop - nop - - moveq r9, #0x1 @ if speed down, post down, drop volt - bleq voltage_shift_c - - mcr p15, 0, r3, c7, c10, 4 @ memory barrier - str r5, [r6] @ set new RFR_1 value - add r6, r6, #0x30 @ get RFR_2 addr - str r5, [r6] @ set RFR_2 - nop - cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL - bne freq_out @ leave if SDR, no DLL function - - /* With DDR, we need to take care of the DLL for the frequency change */ - ldr r2, omap243x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl - str r1, [r2] @ write out new SDRC_DLLA_CTRL - add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL - str r1, [r2] @ commit to SDRC_DLLB_CTRL - mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks -dll_wait: - subs r1, r1, #0x1 - bne dll_wait -freq_out: - ldmfd sp!, {r0 - r10, pc} @ restore regs and return - - /* - * shift up or down voltage, use R9 as input to tell level. - * wait for it to finish, use 32k sync counter, 1tick=31uS. - */ -voltage_shift_c: - ldr r10, omap243x_srs_prcm_voltctrl @ get addr of volt ctrl - ldr r8, [r10] @ get value - ldr r7, ddr_prcm_mask_val @ get value of mask - and r8, r8, r7 @ apply mask to clear bits - orr r8, r8, r9 @ bulld value for L0/L1-volt operation. - str r8, [r10] @ set up for change. - mov r7, #0x4000 @ get val for force - orr r8, r8, r7 @ build value for force - str r8, [r10] @ Force transition to L1 - - ldr r10, omap243x_srs_timer_32ksynct @ get addr of counter - ldr r8, [r10] @ get value - add r8, r8, #0x2 @ give it at most 62uS (min 31+) -volt_delay_c: - ldr r7, [r10] @ get timer value - cmp r8, r7 @ time up? - bhi volt_delay_c @ not yet->branch - mov pc, lr @ back to caller - -omap243x_srs_cm_clksel2_pll: - .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) -omap243x_srs_sdrc_dlla_ctrl: - .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) -omap243x_srs_sdrc_rfr_ctrl: - .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) -omap243x_srs_prcm_voltctrl: - .word OMAP243X_PRCM_VOLTCTRL -ddr_prcm_mask_val: - .word 0xFFFF3FFC -omap243x_srs_timer_32ksynct: - .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) - -ENTRY(omap243x_sram_reprogram_sdrc_sz) - .word . - omap243x_sram_reprogram_sdrc - -/* - * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. - */ -ENTRY(omap243x_sram_set_prcm) - stmfd sp!, {r0-r12, lr} @ regs to stack - adr r4, pbegin @ addr of preload start - adr r8, pend @ addr of preload end - mcrr p15, 1, r8, r4, c12 @ preload into icache -pbegin: - /* move into fast relock bypass */ - ldr r8, omap243x_ssp_pll_ctl @ get addr - ldr r5, [r8] @ get val - mvn r6, #0x3 @ clear mask - and r5, r5, r6 @ clear field - orr r7, r5, #0x2 @ fast relock val - str r7, [r8] @ go to fast relock - ldr r4, omap243x_ssp_pll_stat @ addr of stat -block: - /* wait for bypass */ - ldr r8, [r4] @ stat value - and r8, r8, #0x3 @ mask for stat - cmp r8, #0x1 @ there yet - bne block @ loop if not - - /* set new dpll dividers _after_ in bypass */ - ldr r4, omap243x_ssp_pll_div @ get addr - str r0, [r4] @ set dpll ctrl val - - ldr r4, omap243x_ssp_set_config @ get addr - mov r8, #1 @ valid cfg msk - str r8, [r4] @ make dividers take - - mov r4, #100 @ dead spin a bit -wait_a_bit: - subs r4, r4, #1 @ dec loop - bne wait_a_bit @ delay done? - - /* check if staying in bypass */ - cmp r2, #0x1 @ stay in bypass? - beq pend @ jump over dpll relock - - /* relock DPLL with new vals */ - ldr r5, omap243x_ssp_pll_stat @ get addr - ldr r4, omap243x_ssp_pll_ctl @ get addr - orr r8, r7, #0x3 @ val for lock dpll - str r8, [r4] @ set val - mov r0, #1000 @ dead spin a bit -wait_more: - subs r0, r0, #1 @ dec loop - bne wait_more @ delay done? -wait_lock: - ldr r8, [r5] @ get lock val - and r8, r8, #3 @ isolate field - cmp r8, #2 @ locked? - bne wait_lock @ wait if not -pend: - /* update memory timings & briefly lock dll */ - ldr r4, omap243x_ssp_sdrc_rfr @ get addr - str r1, [r4] @ update refresh timing - ldr r11, omap243x_ssp_dlla_ctrl @ get addr of DLLA ctrl - ldr r10, [r11] @ get current val - mvn r9, #0x4 @ mask to get clear bit2 - and r10, r10, r9 @ clear bit2 for lock mode - orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) - str r10, [r11] @ commit to DLLA_CTRL - add r11, r11, #0x8 @ move to dllb - str r10, [r11] @ hit DLLB also - - mov r4, #0x800 @ relock time (min 0x400 L3 clocks) -wait_dll_lock: - subs r4, r4, #0x1 - bne wait_dll_lock - nop - ldmfd sp!, {r0-r12, pc} @ restore regs and return - -omap243x_ssp_set_config: - .word OMAP243X_PRCM_CLKCFG_CTRL -omap243x_ssp_pll_ctl: - .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN) -omap243x_ssp_pll_stat: - .word OMAP2430_CM_REGADDR(PLL_MOD, CM_IDLEST) -omap243x_ssp_pll_div: - .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL1) -omap243x_ssp_sdrc_rfr: - .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) -omap243x_ssp_dlla_ctrl: - .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) - -ENTRY(omap243x_sram_set_prcm_sz) - .word . - omap243x_sram_set_prcm diff --git a/trunk/arch/arm/mach-omap2/timer-gp.c b/trunk/arch/arm/mach-omap2/timer-gp.c index 557603f99313..78d05f203fff 100644 --- a/trunk/arch/arm/mach-omap2/timer-gp.c +++ b/trunk/arch/arm/mach-omap2/timer-gp.c @@ -59,7 +59,8 @@ static struct irqaction omap2_gp_timer_irq = { static int omap2_gp_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { - omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles); + omap_dm_timer_set_load(gptimer, 0, 0xffffffff - cycles); + omap_dm_timer_start(gptimer); return 0; } @@ -76,7 +77,8 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; period -= 1; - omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period); + omap_dm_timer_set_load(gptimer, 1, 0xffffffff - period); + omap_dm_timer_start(gptimer); break; case CLOCK_EVT_MODE_ONESHOT: break; @@ -170,7 +172,8 @@ static void __init omap2_gp_clocksource_init(void) tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt)); tick_period = (tick_rate / HZ) - 1; - omap_dm_timer_set_load_start(gpt, 1, 0); + omap_dm_timer_set_load(gpt, 1, 0); + omap_dm_timer_start(gpt); clocksource_gpt.mult = clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift); diff --git a/trunk/arch/arm/mach-realview/platsmp.c b/trunk/arch/arm/mach-realview/platsmp.c index 8e813ed57519..3e57428affee 100644 --- a/trunk/arch/arm/mach-realview/platsmp.c +++ b/trunk/arch/arm/mach-realview/platsmp.c @@ -74,8 +74,6 @@ static DEFINE_SPINLOCK(boot_lock); void __cpuinit platform_secondary_init(unsigned int cpu) { - trace_hardirqs_off(); - /* * the primary core may have used a "cross call" soft interrupt * to get this processor out of WFI in the BootMonitor - make diff --git a/trunk/arch/arm/plat-omap/Makefile b/trunk/arch/arm/plat-omap/Makefile index 2c4051cc79a1..bc639a30d6d1 100644 --- a/trunk/arch/arm/plat-omap/Makefile +++ b/trunk/arch/arm/plat-omap/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \ +obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o \ usb.o fb.o obj-m := obj-n := diff --git a/trunk/arch/arm/plat-omap/clock.c b/trunk/arch/arm/plat-omap/clock.c index c2e741de0203..2db5580048d8 100644 --- a/trunk/arch/arm/plat-omap/clock.c +++ b/trunk/arch/arm/plat-omap/clock.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/plat-omap/clock.c * - * Copyright (C) 2004 - 2008 Nokia corporation + * Copyright (C) 2004 - 2005 Nokia corporation * Written by Tuukka Tikkanen * * Modified for omap shared clock framework by Tony Lindgren @@ -22,7 +22,6 @@ #include #include #include -#include #include @@ -34,6 +33,41 @@ static DEFINE_SPINLOCK(clockfw_lock); static struct clk_functions *arch_clock; +#ifdef CONFIG_PM_DEBUG + +static void print_parents(struct clk *clk) +{ + struct clk *p; + int printed = 0; + + list_for_each_entry(p, &clocks, node) { + if (p->parent == clk && p->usecount) { + if (!clk->usecount && !printed) { + printk("MISMATCH: %s\n", clk->name); + printed = 1; + } + printk("\t%-15s\n", p->name); + } + } +} + +void clk_print_usecounts(void) +{ + unsigned long flags; + struct clk *p; + + spin_lock_irqsave(&clockfw_lock, flags); + list_for_each_entry(p, &clocks, node) { + if (p->usecount) + printk("%-15s: %d\n", p->name, p->usecount); + print_parents(p); + + } + spin_unlock_irqrestore(&clockfw_lock, flags); +} + +#endif + /*------------------------------------------------------------------------- * Standard clock functions defined in include/linux/clk.h *-------------------------------------------------------------------------*/ @@ -412,93 +446,3 @@ int __init clk_init(struct clk_functions * custom_clocks) return 0; } -#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) -/* - * debugfs support to trace clock tree hierarchy and attributes - */ -static struct dentry *clk_debugfs_root; - -static int clk_debugfs_register_one(struct clk *c) -{ - int err; - struct dentry *d, *child; - struct clk *pa = c->parent; - char s[255]; - char *p = s; - - p += sprintf(p, "%s", c->name); - if (c->id != 0) - sprintf(p, ":%d", c->id); - d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root); - if (IS_ERR(d)) - return PTR_ERR(d); - c->dent = d; - - d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount); - if (IS_ERR(d)) { - err = PTR_ERR(d); - goto err_out; - } - d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); - if (IS_ERR(d)) { - err = PTR_ERR(d); - goto err_out; - } - d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags); - if (IS_ERR(d)) { - err = PTR_ERR(d); - goto err_out; - } - return 0; - -err_out: - d = c->dent; - list_for_each_entry(child, &d->d_subdirs, d_u.d_child) - debugfs_remove(child); - debugfs_remove(c->dent); - return err; -} - -static int clk_debugfs_register(struct clk *c) -{ - int err; - struct clk *pa = c->parent; - - if (pa && !pa->dent) { - err = clk_debugfs_register(pa); - if (err) - return err; - } - - if (!c->dent) { - err = clk_debugfs_register_one(c); - if (err) - return err; - } - return 0; -} - -static int __init clk_debugfs_init(void) -{ - struct clk *c; - struct dentry *d; - int err; - - d = debugfs_create_dir("clock", NULL); - if (IS_ERR(d)) - return PTR_ERR(d); - clk_debugfs_root = d; - - list_for_each_entry(c, &clocks, node) { - err = clk_debugfs_register(c); - if (err) - goto err_out; - } - return 0; -err_out: - debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */ - return err; -} -late_initcall(clk_debugfs_init); - -#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */ diff --git a/trunk/arch/arm/plat-omap/common.c b/trunk/arch/arm/plat-omap/common.c index 8d04929a3c75..bd1cef2c3c14 100644 --- a/trunk/arch/arm/plat-omap/common.c +++ b/trunk/arch/arm/plat-omap/common.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -242,70 +241,30 @@ arch_initcall(omap_init_clocksource_32k); /* Global address base setup code */ -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) - -static struct omap_globals *omap2_globals; - -static void __init __omap2_set_globals(void) -{ - omap2_set_globals_memory(omap2_globals); - omap2_set_globals_control(omap2_globals); - omap2_set_globals_prcm(omap2_globals); -} - -#endif - #if defined(CONFIG_ARCH_OMAP2420) - -static struct omap_globals omap242x_globals = { - .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x48014000), - .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE), - .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE), - .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE), - .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE), - .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CM_BASE), -}; - void __init omap2_set_globals_242x(void) { - omap2_globals = &omap242x_globals; - __omap2_set_globals(); + omap2_sdrc_base = OMAP2420_SDRC_BASE; + omap2_sms_base = OMAP2420_SMS_BASE; + omap_ctrl_base_set(OMAP2420_CTRL_BASE); } #endif #if defined(CONFIG_ARCH_OMAP2430) - -static struct omap_globals omap243x_globals = { - .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4900a000), - .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE), - .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE), - .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE), - .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE), - .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_CM_BASE), -}; - void __init omap2_set_globals_243x(void) { - omap2_globals = &omap243x_globals; - __omap2_set_globals(); + omap2_sdrc_base = OMAP243X_SDRC_BASE; + omap2_sms_base = OMAP243X_SMS_BASE; + omap_ctrl_base_set(OMAP243X_CTRL_BASE); } #endif #if defined(CONFIG_ARCH_OMAP3430) - -static struct omap_globals omap343x_globals = { - .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4830A000), - .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE), - .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE), - .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE), - .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE), - .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_CM_BASE), -}; - void __init omap2_set_globals_343x(void) { - omap2_globals = &omap343x_globals; - __omap2_set_globals(); + omap2_sdrc_base = OMAP343X_SDRC_BASE; + omap2_sms_base = OMAP343X_SMS_BASE; + omap_ctrl_base_set(OMAP343X_CTRL_BASE); } #endif diff --git a/trunk/arch/arm/plat-omap/devices.c b/trunk/arch/arm/plat-omap/devices.c index 81002b722da1..4a53f9ba6c43 100644 --- a/trunk/arch/arm/plat-omap/devices.c +++ b/trunk/arch/arm/plat-omap/devices.c @@ -24,7 +24,6 @@ #include #include #include -#include #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) @@ -145,53 +144,6 @@ static void omap_init_kp(void) static inline void omap_init_kp(void) {} #endif -/*-------------------------------------------------------------------------*/ -#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE) - -static struct platform_device **omap_mcbsp_devices; - -void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, - int size) -{ - int i; - - if (size > OMAP_MAX_MCBSP_COUNT) { - printk(KERN_WARNING "Registered too many McBSPs platform_data." - " Using maximum (%d) available.\n", - OMAP_MAX_MCBSP_COUNT); - size = OMAP_MAX_MCBSP_COUNT; - } - - omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *), - GFP_KERNEL); - if (!omap_mcbsp_devices) { - printk(KERN_ERR "Could not register McBSP devices\n"); - return; - } - - for (i = 0; i < size; i++) { - struct platform_device *new_mcbsp; - int ret; - - new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1); - if (!new_mcbsp) - continue; - new_mcbsp->dev.platform_data = &config[i]; - ret = platform_device_add(new_mcbsp); - if (ret) { - platform_device_put(new_mcbsp); - continue; - } - omap_mcbsp_devices[i] = new_mcbsp; - } -} - -#else -void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, - int size) -{ } -#endif - /*-------------------------------------------------------------------------*/ #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index fac8e994f588..c00eda588cd8 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/plat-omap/dma.c * - * Copyright (C) 2003 - 2008 Nokia Corporation + * Copyright (C) 2003 Nokia Corporation * Author: Juha Yrjölä * DMA channel linking for 1610 by Samuel Ortiz * Graphics DMA and LCD DMA graphics tranformations @@ -25,11 +25,11 @@ #include #include #include -#include #include #include #include +#include #include @@ -43,13 +43,13 @@ enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, DMA_CH_STARTED, enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED }; #endif -#define OMAP_DMA_ACTIVE 0x01 -#define OMAP_DMA_CCR_EN (1 << 7) +#define OMAP_DMA_ACTIVE 0x01 +#define OMAP_DMA_CCR_EN (1 << 7) #define OMAP2_DMA_CSR_CLEAR_MASK 0xffe -#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) +#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) -static int enable_1510_mode; +static int enable_1510_mode = 0; struct omap_dma_lch { int next_lch; @@ -57,7 +57,7 @@ struct omap_dma_lch { u16 saved_csr; u16 enabled_irqs; const char *dev_name; - void (*callback)(int lch, u16 ch_status, void *data); + void (* callback)(int lch, u16 ch_status, void *data); void *data; #ifndef CONFIG_ARCH_OMAP1 @@ -72,6 +72,7 @@ struct omap_dma_lch { long flags; }; +#ifndef CONFIG_ARCH_OMAP1 struct dma_link_info { int *linked_dmach_q; int no_of_lchs_linked; @@ -85,9 +86,7 @@ struct dma_link_info { }; -static struct dma_link_info *dma_linked_lch; - -#ifndef CONFIG_ARCH_OMAP1 +static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT]; /* Chain handling macros */ #define OMAP_DMA_CHAIN_QINIT(chain_id) \ @@ -120,15 +119,12 @@ static struct dma_link_info *dma_linked_lch; dma_linked_lch[chain_id].q_count++; \ } while (0) #endif - -static int dma_lch_count; static int dma_chan_count; static spinlock_t dma_chan_lock; -static struct omap_dma_lch *dma_chan; -static void __iomem *omap_dma_base; +static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT]; -static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = { +static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = { INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3, INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7, INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10, @@ -143,24 +139,6 @@ static inline void omap_enable_channel_irq(int lch); #define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \ __func__); -#define dma_read(reg) \ -({ \ - u32 __val; \ - if (cpu_class_is_omap1()) \ - __val = __raw_readw(omap_dma_base + OMAP1_DMA_##reg); \ - else \ - __val = __raw_readl(omap_dma_base + OMAP_DMA4_##reg); \ - __val; \ -}) - -#define dma_write(val, reg) \ -({ \ - if (cpu_class_is_omap1()) \ - __raw_writew((u16)(val), omap_dma_base + OMAP1_DMA_##reg); \ - else \ - __raw_writel((val), omap_dma_base + OMAP_DMA4_##reg); \ -}) - #ifdef CONFIG_ARCH_OMAP15XX /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */ int omap_dma_in_1510_mode(void) @@ -195,14 +173,13 @@ static inline void set_gdma_dev(int req, int dev) #define set_gdma_dev(req, dev) do {} while (0) #endif -/* Omap1 only */ static void clear_lch_regs(int lch) { int i; - void __iomem *lch_base = omap_dma_base + OMAP1_DMA_CH_BASE(lch); + u32 lch_base = OMAP_DMA_BASE + lch * 0x40; for (i = 0; i < 0x2c; i += 2) - __raw_writew(0, lch_base + i); + omap_writew(0, lch_base + i); } void omap_set_dma_priority(int lch, int dst_port, int priority) @@ -235,49 +212,33 @@ void omap_set_dma_priority(int lch, int dst_port, int priority) } if (cpu_class_is_omap2()) { - u32 ccr; - - ccr = dma_read(CCR(lch)); if (priority) - ccr |= (1 << 6); + OMAP_DMA_CCR_REG(lch) |= (1 << 6); else - ccr &= ~(1 << 6); - dma_write(ccr, CCR(lch)); + OMAP_DMA_CCR_REG(lch) &= ~(1 << 6); } } -EXPORT_SYMBOL(omap_set_dma_priority); void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, int frame_count, int sync_mode, int dma_trigger, int src_or_dst_synch) { - u32 l; - - l = dma_read(CSDP(lch)); - l &= ~0x03; - l |= data_type; - dma_write(l, CSDP(lch)); + OMAP_DMA_CSDP_REG(lch) &= ~0x03; + OMAP_DMA_CSDP_REG(lch) |= data_type; if (cpu_class_is_omap1()) { - u16 ccr; - - ccr = dma_read(CCR(lch)); - ccr &= ~(1 << 5); + OMAP_DMA_CCR_REG(lch) &= ~(1 << 5); if (sync_mode == OMAP_DMA_SYNC_FRAME) - ccr |= 1 << 5; - dma_write(ccr, CCR(lch)); + OMAP_DMA_CCR_REG(lch) |= 1 << 5; - ccr = dma_read(CCR2(lch)); - ccr &= ~(1 << 2); + OMAP1_DMA_CCR2_REG(lch) &= ~(1 << 2); if (sync_mode == OMAP_DMA_SYNC_BLOCK) - ccr |= 1 << 2; - dma_write(ccr, CCR2(lch)); + OMAP1_DMA_CCR2_REG(lch) |= 1 << 2; } if (cpu_class_is_omap2() && dma_trigger) { - u32 val; + u32 val = OMAP_DMA_CCR_REG(lch); - val = dma_read(CCR(lch)); val &= ~(3 << 19); if (dma_trigger > 63) val |= 1 << 20; @@ -302,13 +263,12 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, else val &= ~(1 << 24); /* dest synch */ - dma_write(val, CCR(lch)); + OMAP_DMA_CCR_REG(lch) = val; } - dma_write(elem_count, CEN(lch)); - dma_write(frame_count, CFN(lch)); + OMAP_DMA_CEN_REG(lch) = elem_count; + OMAP_DMA_CFN_REG(lch) = frame_count; } -EXPORT_SYMBOL(omap_set_dma_transfer_params); void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) { @@ -321,9 +281,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) return; } - w = dma_read(CCR2(lch)); - w &= ~0x03; - + w = OMAP1_DMA_CCR2_REG(lch) & ~0x03; switch (mode) { case OMAP_DMA_CONSTANT_FILL: w |= 0x01; @@ -336,81 +294,52 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) default: BUG(); } - dma_write(w, CCR2(lch)); + OMAP1_DMA_CCR2_REG(lch) = w; - w = dma_read(LCH_CTRL(lch)); - w &= ~0x0f; + w = OMAP1_DMA_LCH_CTRL_REG(lch) & ~0x0f; /* Default is channel type 2D */ if (mode) { - dma_write((u16)color, COLOR_L(lch)); - dma_write((u16)(color >> 16), COLOR_U(lch)); + OMAP1_DMA_COLOR_L_REG(lch) = (u16)color; + OMAP1_DMA_COLOR_U_REG(lch) = (u16)(color >> 16); w |= 1; /* Channel type G */ } - dma_write(w, LCH_CTRL(lch)); + OMAP1_DMA_LCH_CTRL_REG(lch) = w; } -EXPORT_SYMBOL(omap_set_dma_color_mode); void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) { if (cpu_class_is_omap2()) { - u32 csdp; - - csdp = dma_read(CSDP(lch)); - csdp &= ~(0x3 << 16); - csdp |= (mode << 16); - dma_write(csdp, CSDP(lch)); - } -} -EXPORT_SYMBOL(omap_set_dma_write_mode); - -void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode) -{ - if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { - u32 l; - - l = dma_read(LCH_CTRL(lch)); - l &= ~0x7; - l |= mode; - dma_write(l, LCH_CTRL(lch)); + OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16); + OMAP_DMA_CSDP_REG(lch) |= (mode << 16); } } -EXPORT_SYMBOL(omap_set_dma_channel_mode); /* Note that src_port is only for omap1 */ void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, int src_ei, int src_fi) { - u32 l; - if (cpu_class_is_omap1()) { - u16 w; - - w = dma_read(CSDP(lch)); - w &= ~(0x1f << 2); - w |= src_port << 2; - dma_write(w, CSDP(lch)); + OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 2); + OMAP_DMA_CSDP_REG(lch) |= src_port << 2; } - l = dma_read(CCR(lch)); - l &= ~(0x03 << 12); - l |= src_amode << 12; - dma_write(l, CCR(lch)); + OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 12); + OMAP_DMA_CCR_REG(lch) |= src_amode << 12; if (cpu_class_is_omap1()) { - dma_write(src_start >> 16, CSSA_U(lch)); - dma_write((u16)src_start, CSSA_L(lch)); + OMAP1_DMA_CSSA_U_REG(lch) = src_start >> 16; + OMAP1_DMA_CSSA_L_REG(lch) = src_start; } if (cpu_class_is_omap2()) - dma_write(src_start, CSSA(lch)); + OMAP2_DMA_CSSA_REG(lch) = src_start; - dma_write(src_ei, CSEI(lch)); - dma_write(src_fi, CSFI(lch)); + OMAP_DMA_CSEI_REG(lch) = src_ei; + OMAP_DMA_CSFI_REG(lch) = src_fi; } -EXPORT_SYMBOL(omap_set_dma_src_params); -void omap_set_dma_params(int lch, struct omap_dma_channel_params *params) +void omap_set_dma_params(int lch, struct omap_dma_channel_params * params) { omap_set_dma_transfer_params(lch, params->data_type, params->elem_count, params->frame_count, @@ -427,37 +356,28 @@ void omap_set_dma_params(int lch, struct omap_dma_channel_params *params) omap_dma_set_prio_lch(lch, params->read_prio, params->write_prio); } -EXPORT_SYMBOL(omap_set_dma_params); void omap_set_dma_src_index(int lch, int eidx, int fidx) { - if (cpu_class_is_omap2()) + if (cpu_class_is_omap2()) { + REVISIT_24XX(); return; - - dma_write(eidx, CSEI(lch)); - dma_write(fidx, CSFI(lch)); + } + OMAP_DMA_CSEI_REG(lch) = eidx; + OMAP_DMA_CSFI_REG(lch) = fidx; } -EXPORT_SYMBOL(omap_set_dma_src_index); void omap_set_dma_src_data_pack(int lch, int enable) { - u32 l; - - l = dma_read(CSDP(lch)); - l &= ~(1 << 6); + OMAP_DMA_CSDP_REG(lch) &= ~(1 << 6); if (enable) - l |= (1 << 6); - dma_write(l, CSDP(lch)); + OMAP_DMA_CSDP_REG(lch) |= (1 << 6); } -EXPORT_SYMBOL(omap_set_dma_src_data_pack); void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) { unsigned int burst = 0; - u32 l; - - l = dma_read(CSDP(lch)); - l &= ~(0x03 << 7); + OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7); switch (burst_mode) { case OMAP_DMA_DATA_BURST_DIS: @@ -488,73 +408,55 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) default: BUG(); } - - l |= (burst << 7); - dma_write(l, CSDP(lch)); + OMAP_DMA_CSDP_REG(lch) |= (burst << 7); } -EXPORT_SYMBOL(omap_set_dma_src_burst_mode); /* Note that dest_port is only for OMAP1 */ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, unsigned long dest_start, int dst_ei, int dst_fi) { - u32 l; - if (cpu_class_is_omap1()) { - l = dma_read(CSDP(lch)); - l &= ~(0x1f << 9); - l |= dest_port << 9; - dma_write(l, CSDP(lch)); + OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 9); + OMAP_DMA_CSDP_REG(lch) |= dest_port << 9; } - l = dma_read(CCR(lch)); - l &= ~(0x03 << 14); - l |= dest_amode << 14; - dma_write(l, CCR(lch)); + OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 14); + OMAP_DMA_CCR_REG(lch) |= dest_amode << 14; if (cpu_class_is_omap1()) { - dma_write(dest_start >> 16, CDSA_U(lch)); - dma_write(dest_start, CDSA_L(lch)); + OMAP1_DMA_CDSA_U_REG(lch) = dest_start >> 16; + OMAP1_DMA_CDSA_L_REG(lch) = dest_start; } if (cpu_class_is_omap2()) - dma_write(dest_start, CDSA(lch)); + OMAP2_DMA_CDSA_REG(lch) = dest_start; - dma_write(dst_ei, CDEI(lch)); - dma_write(dst_fi, CDFI(lch)); + OMAP_DMA_CDEI_REG(lch) = dst_ei; + OMAP_DMA_CDFI_REG(lch) = dst_fi; } -EXPORT_SYMBOL(omap_set_dma_dest_params); void omap_set_dma_dest_index(int lch, int eidx, int fidx) { - if (cpu_class_is_omap2()) + if (cpu_class_is_omap2()) { + REVISIT_24XX(); return; - - dma_write(eidx, CDEI(lch)); - dma_write(fidx, CDFI(lch)); + } + OMAP_DMA_CDEI_REG(lch) = eidx; + OMAP_DMA_CDFI_REG(lch) = fidx; } -EXPORT_SYMBOL(omap_set_dma_dest_index); void omap_set_dma_dest_data_pack(int lch, int enable) { - u32 l; - - l = dma_read(CSDP(lch)); - l &= ~(1 << 13); + OMAP_DMA_CSDP_REG(lch) &= ~(1 << 13); if (enable) - l |= 1 << 13; - dma_write(l, CSDP(lch)); + OMAP_DMA_CSDP_REG(lch) |= 1 << 13; } -EXPORT_SYMBOL(omap_set_dma_dest_data_pack); void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) { unsigned int burst = 0; - u32 l; - - l = dma_read(CSDP(lch)); - l &= ~(0x03 << 14); + OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14); switch (burst_mode) { case OMAP_DMA_DATA_BURST_DIS: @@ -584,10 +486,8 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) BUG(); return; } - l |= (burst << 14); - dma_write(l, CSDP(lch)); + OMAP_DMA_CSDP_REG(lch) |= (burst << 14); } -EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); static inline void omap_enable_channel_irq(int lch) { @@ -595,74 +495,64 @@ static inline void omap_enable_channel_irq(int lch) /* Clear CSR */ if (cpu_class_is_omap1()) - status = dma_read(CSR(lch)); + status = OMAP_DMA_CSR_REG(lch); else if (cpu_class_is_omap2()) - dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch)); + OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; /* Enable some nice interrupts. */ - dma_write(dma_chan[lch].enabled_irqs, CICR(lch)); + OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs; + + dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } static void omap_disable_channel_irq(int lch) { if (cpu_class_is_omap2()) - dma_write(0, CICR(lch)); + OMAP_DMA_CICR_REG(lch) = 0; } void omap_enable_dma_irq(int lch, u16 bits) { dma_chan[lch].enabled_irqs |= bits; } -EXPORT_SYMBOL(omap_enable_dma_irq); void omap_disable_dma_irq(int lch, u16 bits) { dma_chan[lch].enabled_irqs &= ~bits; } -EXPORT_SYMBOL(omap_disable_dma_irq); static inline void enable_lnk(int lch) { - u32 l; - - l = dma_read(CLNK_CTRL(lch)); - if (cpu_class_is_omap1()) - l &= ~(1 << 14); + OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 14); /* Set the ENABLE_LNK bits */ if (dma_chan[lch].next_lch != -1) - l = dma_chan[lch].next_lch | (1 << 15); + OMAP_DMA_CLNK_CTRL_REG(lch) = + dma_chan[lch].next_lch | (1 << 15); #ifndef CONFIG_ARCH_OMAP1 - if (cpu_class_is_omap2()) - if (dma_chan[lch].next_linked_ch != -1) - l = dma_chan[lch].next_linked_ch | (1 << 15); + if (dma_chan[lch].next_linked_ch != -1) + OMAP_DMA_CLNK_CTRL_REG(lch) = + dma_chan[lch].next_linked_ch | (1 << 15); #endif - - dma_write(l, CLNK_CTRL(lch)); } static inline void disable_lnk(int lch) { - u32 l; - - l = dma_read(CLNK_CTRL(lch)); - /* Disable interrupts */ if (cpu_class_is_omap1()) { - dma_write(0, CICR(lch)); + OMAP_DMA_CICR_REG(lch) = 0; /* Set the STOP_LNK bit */ - l |= 1 << 14; + OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14; } if (cpu_class_is_omap2()) { omap_disable_channel_irq(lch); /* Clear the ENABLE_LNK bit */ - l &= ~(1 << 15); + OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15); } - dma_write(l, CLNK_CTRL(lch)); dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; } @@ -673,13 +563,13 @@ static inline void omap2_enable_irq_lch(int lch) if (!cpu_class_is_omap2()) return; - val = dma_read(IRQENABLE_L0); + val = omap_readl(OMAP_DMA4_IRQENABLE_L0); val |= 1 << lch; - dma_write(val, IRQENABLE_L0); + omap_writel(val, OMAP_DMA4_IRQENABLE_L0); } int omap_request_dma(int dev_id, const char *dev_name, - void (*callback)(int lch, u16 ch_status, void *data), + void (* callback)(int lch, u16 ch_status, void *data), void *data, int *dma_ch_out) { int ch, free_ch = -1; @@ -712,14 +602,10 @@ int omap_request_dma(int dev_id, const char *dev_name, chan->dev_name = dev_name; chan->callback = callback; chan->data = data; - #ifndef CONFIG_ARCH_OMAP1 - if (cpu_class_is_omap2()) { - chan->chain_id = -1; - chan->next_linked_ch = -1; - } + chan->chain_id = -1; + chan->next_linked_ch = -1; #endif - chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; if (cpu_class_is_omap1()) @@ -734,28 +620,26 @@ int omap_request_dma(int dev_id, const char *dev_name, set_gdma_dev(free_ch + 1, dev_id); dev_id = free_ch + 1; } - /* - * Disable the 1510 compatibility mode and set the sync device - * id. - */ - dma_write(dev_id | (1 << 10), CCR(free_ch)); + /* Disable the 1510 compatibility mode and set the sync device + * id. */ + OMAP_DMA_CCR_REG(free_ch) = dev_id | (1 << 10); } else if (cpu_is_omap730() || cpu_is_omap15xx()) { - dma_write(dev_id, CCR(free_ch)); + OMAP_DMA_CCR_REG(free_ch) = dev_id; } if (cpu_class_is_omap2()) { omap2_enable_irq_lch(free_ch); + omap_enable_channel_irq(free_ch); /* Clear the CSR register and IRQ status register */ - dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(free_ch)); - dma_write(1 << free_ch, IRQSTATUS_L0); + OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK; + omap_writel(1 << free_ch, OMAP_DMA4_IRQSTATUS_L0); } *dma_ch_out = free_ch; return 0; } -EXPORT_SYMBOL(omap_request_dma); void omap_free_dma(int lch) { @@ -763,12 +647,11 @@ void omap_free_dma(int lch) spin_lock_irqsave(&dma_chan_lock, flags); if (dma_chan[lch].dev_id == -1) { - pr_err("omap_dma: trying to free unallocated DMA channel %d\n", + printk("omap_dma: trying to free nonallocated DMA channel %d\n", lch); spin_unlock_irqrestore(&dma_chan_lock, flags); return; } - dma_chan[lch].dev_id = -1; dma_chan[lch].next_lch = -1; dma_chan[lch].callback = NULL; @@ -776,31 +659,30 @@ void omap_free_dma(int lch) if (cpu_class_is_omap1()) { /* Disable all DMA interrupts for the channel. */ - dma_write(0, CICR(lch)); + OMAP_DMA_CICR_REG(lch) = 0; /* Make sure the DMA transfer is stopped. */ - dma_write(0, CCR(lch)); + OMAP_DMA_CCR_REG(lch) = 0; } if (cpu_class_is_omap2()) { u32 val; /* Disable interrupts */ - val = dma_read(IRQENABLE_L0); + val = omap_readl(OMAP_DMA4_IRQENABLE_L0); val &= ~(1 << lch); - dma_write(val, IRQENABLE_L0); + omap_writel(val, OMAP_DMA4_IRQENABLE_L0); /* Clear the CSR register and IRQ status register */ - dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(lch)); - dma_write(1 << lch, IRQSTATUS_L0); + OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; + omap_writel(1 << lch, OMAP_DMA4_IRQSTATUS_L0); /* Disable all DMA interrupts for the channel. */ - dma_write(0, CICR(lch)); + OMAP_DMA_CICR_REG(lch) = 0; /* Make sure the DMA transfer is stopped. */ - dma_write(0, CCR(lch)); + OMAP_DMA_CCR_REG(lch) = 0; omap_clear_dma(lch); } } -EXPORT_SYMBOL(omap_free_dma); /** * @brief omap_dma_set_global_params : Set global priority settings for dma @@ -828,7 +710,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) reg = (arb_rate & 0xff) << 16; reg |= (0xff & max_fifo_depth); - dma_write(reg, GCR); + omap_writel(reg, OMAP_DMA4_GCR_REG); } EXPORT_SYMBOL(omap_dma_set_global_params); @@ -845,21 +727,20 @@ int omap_dma_set_prio_lch(int lch, unsigned char read_prio, unsigned char write_prio) { - u32 l; + u32 w; - if (unlikely((lch < 0 || lch >= dma_lch_count))) { + if (unlikely((lch < 0 || lch >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid channel id\n"); return -EINVAL; } - l = dma_read(CCR(lch)); - l &= ~((1 << 6) | (1 << 26)); + w = OMAP_DMA_CCR_REG(lch); + w &= ~((1 << 6) | (1 << 26)); if (cpu_is_omap2430() || cpu_is_omap34xx()) - l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26); + w |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26); else - l |= ((read_prio & 0x1) << 6); - - dma_write(l, CCR(lch)); + w |= ((read_prio & 0x1) << 6); + OMAP_DMA_CCR_REG(lch) = w; return 0; } EXPORT_SYMBOL(omap_dma_set_prio_lch); @@ -875,34 +756,28 @@ void omap_clear_dma(int lch) local_irq_save(flags); if (cpu_class_is_omap1()) { - u32 l; - - l = dma_read(CCR(lch)); - l &= ~OMAP_DMA_CCR_EN; - dma_write(l, CCR(lch)); + int status; + OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN; /* Clear pending interrupts */ - l = dma_read(CSR(lch)); + status = OMAP_DMA_CSR_REG(lch); } if (cpu_class_is_omap2()) { int i; - void __iomem *lch_base = omap_dma_base + OMAP_DMA4_CH_BASE(lch); + u32 lch_base = OMAP_DMA4_BASE + lch * 0x60 + 0x80; for (i = 0; i < 0x44; i += 4) - __raw_writel(0, lch_base + i); + omap_writel(0, lch_base + i); } local_irq_restore(flags); } -EXPORT_SYMBOL(omap_clear_dma); void omap_start_dma(int lch) { - u32 l; - if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch; - char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; + char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; dma_chan_link_map[lch] = 1; /* Set the link register of the first channel */ @@ -926,34 +801,27 @@ void omap_start_dma(int lch) } while (next_lch != -1); } else if (cpu_class_is_omap2()) { /* Errata: Need to write lch even if not using chaining */ - dma_write(lch, CLNK_CTRL(lch)); + OMAP_DMA_CLNK_CTRL_REG(lch) = lch; } omap_enable_channel_irq(lch); - l = dma_read(CCR(lch)); - - /* - * Errata: On ES2.0 BUFFERING disable must be set. - * This will always fail on ES1.0 - */ - if (cpu_is_omap24xx()) - l |= OMAP_DMA_CCR_EN; + /* Errata: On ES2.0 BUFFERING disable must be set. + * This will always fail on ES1.0 */ + if (cpu_is_omap24xx()) { + OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN; + } - l |= OMAP_DMA_CCR_EN; - dma_write(l, CCR(lch)); + OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN; dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } -EXPORT_SYMBOL(omap_start_dma); void omap_stop_dma(int lch) { - u32 l; - if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; - char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT]; + char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT]; memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map)); do { @@ -974,22 +842,18 @@ void omap_stop_dma(int lch) /* Disable all interrupts on the channel */ if (cpu_class_is_omap1()) - dma_write(0, CICR(lch)); - - l = dma_read(CCR(lch)); - l &= ~OMAP_DMA_CCR_EN; - dma_write(l, CCR(lch)); + OMAP_DMA_CICR_REG(lch) = 0; + OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN; dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; } -EXPORT_SYMBOL(omap_stop_dma); /* * Allows changing the DMA callback function or data. This may be needed if * the driver shares a single DMA channel for multiple dma triggers. */ int omap_set_dma_callback(int lch, - void (*callback)(int lch, u16 ch_status, void *data), + void (* callback)(int lch, u16 ch_status, void *data), void *data) { unsigned long flags; @@ -1009,7 +873,6 @@ int omap_set_dma_callback(int lch, return 0; } -EXPORT_SYMBOL(omap_set_dma_callback); /* * Returns current physical source address for the given DMA channel. @@ -1023,24 +886,15 @@ dma_addr_t omap_get_dma_src_pos(int lch) { dma_addr_t offset = 0; - if (cpu_is_omap15xx()) - offset = dma_read(CPC(lch)); - else - offset = dma_read(CSAC(lch)); - - /* - * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is - * read before the DMA controller finished disabling the channel. - */ - if (!cpu_is_omap15xx() && offset == 0) - offset = dma_read(CSAC(lch)); - if (cpu_class_is_omap1()) - offset |= (dma_read(CSSA_U(lch)) << 16); + offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) | + (OMAP1_DMA_CSSA_U_REG(lch) << 16)); + + if (cpu_class_is_omap2()) + offset = OMAP_DMA_CSAC_REG(lch); return offset; } -EXPORT_SYMBOL(omap_get_dma_src_pos); /* * Returns current physical destination address for the given DMA channel. @@ -1054,30 +908,25 @@ dma_addr_t omap_get_dma_dst_pos(int lch) { dma_addr_t offset = 0; - if (cpu_is_omap15xx()) - offset = dma_read(CPC(lch)); - else - offset = dma_read(CDAC(lch)); - - /* - * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is - * read before the DMA controller finished disabling the channel. - */ - if (!cpu_is_omap15xx() && offset == 0) - offset = dma_read(CDAC(lch)); - if (cpu_class_is_omap1()) - offset |= (dma_read(CDSA_U(lch)) << 16); + offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) | + (OMAP1_DMA_CDSA_U_REG(lch) << 16)); + + if (cpu_class_is_omap2()) + offset = OMAP_DMA_CDAC_REG(lch); return offset; } -EXPORT_SYMBOL(omap_get_dma_dst_pos); -int omap_get_dma_active_status(int lch) +/* + * Returns current source transfer counting for the given DMA channel. + * Can be used to monitor the progress of a transfer inside a block. + * It must be called with disabled interrupts. + */ +int omap_get_dma_src_addr_counter(int lch) { - return (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) != 0; + return (dma_addr_t) OMAP_DMA_CSAC_REG(lch); } -EXPORT_SYMBOL(omap_get_dma_active_status); int omap_dma_running(void) { @@ -1089,7 +938,7 @@ int omap_dma_running(void) return 1; for (lch = 0; lch < dma_chan_count; lch++) - if (dma_read(CCR(lch)) & OMAP_DMA_CCR_EN) + if (OMAP_DMA_CCR_REG(lch) & OMAP_DMA_CCR_EN) return 1; return 0; @@ -1100,7 +949,7 @@ int omap_dma_running(void) * For this DMA link to start, you still need to start (see omap_start_dma) * the first one. That will fire up the entire queue. */ -void omap_dma_link_lch(int lch_head, int lch_queue) +void omap_dma_link_lch (int lch_head, int lch_queue) { if (omap_dma_in_1510_mode()) { printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); @@ -1117,12 +966,11 @@ void omap_dma_link_lch(int lch_head, int lch_queue) dma_chan[lch_head].next_lch = lch_queue; } -EXPORT_SYMBOL(omap_dma_link_lch); /* * Once the DMA queue is stopped, we can destroy it. */ -void omap_dma_unlink_lch(int lch_head, int lch_queue) +void omap_dma_unlink_lch (int lch_head, int lch_queue) { if (omap_dma_in_1510_mode()) { printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); @@ -1137,6 +985,7 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue) dump_stack(); } + if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) || (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) { printk(KERN_ERR "omap_dma: You need to stop the DMA channels " @@ -1146,15 +995,12 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue) dma_chan[lch_head].next_lch = -1; } -EXPORT_SYMBOL(omap_dma_unlink_lch); - -/*----------------------------------------------------------------------------*/ #ifndef CONFIG_ARCH_OMAP1 /* Create chain of DMA channesls */ static void create_dma_lch_chain(int lch_head, int lch_queue) { - u32 l; + u32 w; /* Check if this is the first link in chain */ if (dma_chan[lch_head].next_linked_ch == -1) { @@ -1174,15 +1020,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue) lch_queue; } - l = dma_read(CLNK_CTRL(lch_head)); - l &= ~(0x1f); - l |= lch_queue; - dma_write(l, CLNK_CTRL(lch_head)); + w = OMAP_DMA_CLNK_CTRL_REG(lch_head); + w &= ~(0x1f); + w |= lch_queue; + OMAP_DMA_CLNK_CTRL_REG(lch_head) = w; - l = dma_read(CLNK_CTRL(lch_queue)); - l &= ~(0x1f); - l |= (dma_chan[lch_queue].next_linked_ch); - dma_write(l, CLNK_CTRL(lch_queue)); + w = OMAP_DMA_CLNK_CTRL_REG(lch_queue); + w &= ~(0x1f); + w |= (dma_chan[lch_queue].next_linked_ch); + OMAP_DMA_CLNK_CTRL_REG(lch_queue) = w; } /** @@ -1217,7 +1063,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, } if (unlikely((no_of_chans < 1 - || no_of_chans > dma_lch_count))) { + || no_of_chans > OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid Number of channels requested\n"); return -EINVAL; } @@ -1272,7 +1118,6 @@ int omap_request_dma_chain(int dev_id, const char *dev_name, for (i = 0; i < (no_of_chans - 1); i++) create_dma_lch_chain(channels[i], channels[i + 1]); } - return 0; } EXPORT_SYMBOL(omap_request_dma_chain); @@ -1295,7 +1140,7 @@ int omap_modify_dma_chain_params(int chain_id, /* Check for input params */ if (unlikely((chain_id < 0 - || chain_id >= dma_lch_count))) { + || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1315,7 +1160,6 @@ int omap_modify_dma_chain_params(int chain_id, */ omap_set_dma_params(channels[i], ¶ms); } - return 0; } EXPORT_SYMBOL(omap_modify_dma_chain_params); @@ -1334,7 +1178,7 @@ int omap_free_dma_chain(int chain_id) u32 i; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1359,7 +1203,6 @@ int omap_free_dma_chain(int chain_id) dma_linked_lch[chain_id].linked_dmach_q = NULL; dma_linked_lch[chain_id].chain_mode = -1; dma_linked_lch[chain_id].chain_state = -1; - return (0); } EXPORT_SYMBOL(omap_free_dma_chain); @@ -1375,7 +1218,7 @@ EXPORT_SYMBOL(omap_free_dma_chain); int omap_dma_chain_status(int chain_id) { /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1390,7 +1233,6 @@ int omap_dma_chain_status(int chain_id) if (OMAP_DMA_CHAIN_QEMPTY(chain_id)) return OMAP_DMA_CHAIN_INACTIVE; - return OMAP_DMA_CHAIN_ACTIVE; } EXPORT_SYMBOL(omap_dma_chain_status); @@ -1413,13 +1255,11 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, int elem_count, int frame_count, void *callbk_data) { int *channels; - u32 l, lch; + u32 w, lch; int start_dma = 0; - /* - * if buffer size is less than 1 then there is - * no use of starting the chain - */ + /* if buffer size is less than 1 then there is + * no use of starting the chain */ if (elem_count < 1) { printk(KERN_ERR "Invalid buffer size\n"); return -EINVAL; @@ -1427,7 +1267,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, /* Check for input params */ if (unlikely((chain_id < 0 - || chain_id >= dma_lch_count))) { + || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1456,24 +1296,20 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, /* Set the params to the free channel */ if (src_start != 0) - dma_write(src_start, CSSA(lch)); + OMAP2_DMA_CSSA_REG(lch) = src_start; if (dest_start != 0) - dma_write(dest_start, CDSA(lch)); + OMAP2_DMA_CDSA_REG(lch) = dest_start; /* Write the buffer size */ - dma_write(elem_count, CEN(lch)); - dma_write(frame_count, CFN(lch)); + OMAP_DMA_CEN_REG(lch) = elem_count; + OMAP_DMA_CFN_REG(lch) = frame_count; - /* - * If the chain is dynamically linked, - * then we may have to start the chain if its not active - */ + /* If the chain is dynamically linked, + * then we may have to start the chain if its not active */ if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_DYNAMIC_CHAIN) { - /* - * In Dynamic chain, if the chain is not started, - * queue the channel - */ + /* In Dynamic chain, if the chain is not started, + * queue the channel */ if (dma_linked_lch[chain_id].chain_state == DMA_CHAIN_NOTSTARTED) { /* Enable the link in previous channel */ @@ -1483,10 +1319,8 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, dma_chan[lch].state = DMA_CH_QUEUED; } - /* - * Chain is already started, make sure its active, - * if not then start the chain - */ + /* Chain is already started, make sure its active, + * if not then start the chain */ else { start_dma = 1; @@ -1495,8 +1329,8 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, enable_lnk(dma_chan[lch].prev_linked_ch); dma_chan[lch].state = DMA_CH_QUEUED; start_dma = 0; - if (0 == ((1 << 7) & dma_read( - CCR(dma_chan[lch].prev_linked_ch)))) { + if (0 == ((1 << 7) & (OMAP_DMA_CCR_REG + (dma_chan[lch].prev_linked_ch)))) { disable_lnk(dma_chan[lch]. prev_linked_ch); pr_debug("\n prev ch is stopped\n"); @@ -1512,28 +1346,27 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, } omap_enable_channel_irq(lch); - l = dma_read(CCR(lch)); + w = OMAP_DMA_CCR_REG(lch); - if ((0 == (l & (1 << 24)))) - l &= ~(1 << 25); + if ((0 == (w & (1 << 24)))) + w &= ~(1 << 25); else - l |= (1 << 25); + w |= (1 << 25); if (start_dma == 1) { - if (0 == (l & (1 << 7))) { - l |= (1 << 7); + if (0 == (w & (1 << 7))) { + w |= (1 << 7); dma_chan[lch].state = DMA_CH_STARTED; pr_debug("starting %d\n", lch); - dma_write(l, CCR(lch)); + OMAP_DMA_CCR_REG(lch) = w; } else start_dma = 0; } else { - if (0 == (l & (1 << 7))) - dma_write(l, CCR(lch)); + if (0 == (w & (1 << 7))) + OMAP_DMA_CCR_REG(lch) = w; } dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } } - return 0; } EXPORT_SYMBOL(omap_dma_chain_a_transfer); @@ -1549,9 +1382,9 @@ EXPORT_SYMBOL(omap_dma_chain_a_transfer); int omap_start_dma_chain_transfers(int chain_id) { int *channels; - u32 l, i; + u32 w, i; - if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1573,19 +1406,18 @@ int omap_start_dma_chain_transfers(int chain_id) omap_enable_channel_irq(channels[0]); } - l = dma_read(CCR(channels[0])); - l |= (1 << 7); + w = OMAP_DMA_CCR_REG(channels[0]); + w |= (1 << 7); dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED; dma_chan[channels[0]].state = DMA_CH_STARTED; - if ((0 == (l & (1 << 24)))) - l &= ~(1 << 25); + if ((0 == (w & (1 << 24)))) + w &= ~(1 << 25); else - l |= (1 << 25); - dma_write(l, CCR(channels[0])); + w |= (1 << 25); + OMAP_DMA_CCR_REG(channels[0]) = w; dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE; - return 0; } EXPORT_SYMBOL(omap_start_dma_chain_transfers); @@ -1601,11 +1433,11 @@ EXPORT_SYMBOL(omap_start_dma_chain_transfers); int omap_stop_dma_chain_transfers(int chain_id) { int *channels; - u32 l, i; + u32 w, i; u32 sys_cf; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1617,22 +1449,21 @@ int omap_stop_dma_chain_transfers(int chain_id) } channels = dma_linked_lch[chain_id].linked_dmach_q; - /* - * DMA Errata: + /* DMA Errata: * Special programming model needed to disable DMA before end of block */ - sys_cf = dma_read(OCP_SYSCONFIG); - l = sys_cf; + sys_cf = omap_readl(OMAP_DMA4_OCP_SYSCONFIG); + w = sys_cf; /* Middle mode reg set no Standby */ - l &= ~((1 << 12)|(1 << 13)); - dma_write(l, OCP_SYSCONFIG); + w &= ~((1 << 12)|(1 << 13)); + omap_writel(w, OMAP_DMA4_OCP_SYSCONFIG); for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) { /* Stop the Channel transmission */ - l = dma_read(CCR(channels[i])); - l &= ~(1 << 7); - dma_write(l, CCR(channels[i])); + w = OMAP_DMA_CCR_REG(channels[i]); + w &= ~(1 << 7); + OMAP_DMA_CCR_REG(channels[i]) = w; /* Disable the link in all the channels */ disable_lnk(channels[i]); @@ -1645,8 +1476,7 @@ int omap_stop_dma_chain_transfers(int chain_id) OMAP_DMA_CHAIN_QINIT(chain_id); /* Errata - put in the old value */ - dma_write(sys_cf, OCP_SYSCONFIG); - + omap_writel(sys_cf, OMAP_DMA4_OCP_SYSCONFIG); return 0; } EXPORT_SYMBOL(omap_stop_dma_chain_transfers); @@ -1669,7 +1499,7 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi) int *channels; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1687,8 +1517,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi) /* Get the current channel */ lch = channels[dma_linked_lch[chain_id].q_head]; - *ei = dma_read(CCEN(lch)); - *fi = dma_read(CCFN(lch)); + *ei = OMAP2_DMA_CCEN_REG(lch); + *fi = OMAP2_DMA_CCFN_REG(lch); return 0; } @@ -1709,7 +1539,7 @@ int omap_get_dma_chain_dst_pos(int chain_id) int *channels; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1725,7 +1555,7 @@ int omap_get_dma_chain_dst_pos(int chain_id) /* Get the current channel */ lch = channels[dma_linked_lch[chain_id].q_head]; - return dma_read(CDAC(lch)); + return (OMAP_DMA_CDAC_REG(lch)); } EXPORT_SYMBOL(omap_get_dma_chain_dst_pos); @@ -1743,7 +1573,7 @@ int omap_get_dma_chain_src_pos(int chain_id) int *channels; /* Check for input params */ - if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) { + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { printk(KERN_ERR "Invalid chain id\n"); return -EINVAL; } @@ -1759,10 +1589,10 @@ int omap_get_dma_chain_src_pos(int chain_id) /* Get the current channel */ lch = channels[dma_linked_lch[chain_id].q_head]; - return dma_read(CSAC(lch)); + return (OMAP_DMA_CSAC_REG(lch)); } EXPORT_SYMBOL(omap_get_dma_chain_src_pos); -#endif /* ifndef CONFIG_ARCH_OMAP1 */ +#endif /*----------------------------------------------------------------------------*/ @@ -1770,13 +1600,13 @@ EXPORT_SYMBOL(omap_get_dma_chain_src_pos); static int omap1_dma_handle_ch(int ch) { - u32 csr; + u16 csr; if (enable_1510_mode && ch >= 6) { csr = dma_chan[ch].saved_csr; dma_chan[ch].saved_csr = 0; } else - csr = dma_read(CSR(ch)); + csr = OMAP_DMA_CSR_REG(ch); if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) { dma_chan[ch + 6].saved_csr = csr >> 7; csr &= 0x7f; @@ -1798,7 +1628,6 @@ static int omap1_dma_handle_ch(int ch) dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE; if (likely(dma_chan[ch].callback != NULL)) dma_chan[ch].callback(ch, csr, dma_chan[ch].data); - return 1; } @@ -1829,13 +1658,12 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id) static int omap2_dma_handle_ch(int ch) { - u32 status = dma_read(CSR(ch)); + u32 status = OMAP_DMA_CSR_REG(ch); if (!status) { if (printk_ratelimit()) - printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", - ch); - dma_write(1 << ch, IRQSTATUS_L0); + printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", ch); + omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0); return 0; } if (unlikely(dma_chan[ch].dev_id == -1)) { @@ -1858,14 +1686,14 @@ static int omap2_dma_handle_ch(int ch) printk(KERN_INFO "DMA misaligned error with device %d\n", dma_chan[ch].dev_id); - dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR(ch)); - dma_write(1 << ch, IRQSTATUS_L0); + OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK; + omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0); /* If the ch is not chained then chain_id will be -1 */ if (dma_chan[ch].chain_id != -1) { int chain_id = dma_chan[ch].chain_id; dma_chan[ch].state = DMA_CH_NOTSTARTED; - if (dma_read(CLNK_CTRL(ch)) & (1 << 15)) + if (OMAP_DMA_CLNK_CTRL_REG(ch) & (1 << 15)) dma_chan[dma_chan[ch].next_linked_ch].state = DMA_CH_STARTED; if (dma_linked_lch[chain_id].chain_mode == @@ -1875,13 +1703,13 @@ static int omap2_dma_handle_ch(int ch) if (!OMAP_DMA_CHAIN_QEMPTY(chain_id)) OMAP_DMA_CHAIN_INCQHEAD(chain_id); - status = dma_read(CSR(ch)); + status = OMAP_DMA_CSR_REG(ch); } if (likely(dma_chan[ch].callback != NULL)) dma_chan[ch].callback(ch, status, dma_chan[ch].data); - dma_write(status, CSR(ch)); + OMAP_DMA_CSR_REG(ch) = status; return 0; } @@ -1892,13 +1720,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id) u32 val; int i; - val = dma_read(IRQSTATUS_L0); + val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); if (val == 0) { if (printk_ratelimit()) printk(KERN_WARNING "Spurious DMA IRQ\n"); return IRQ_HANDLED; } - for (i = 0; i < dma_lch_count && val != 0; i++) { + for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) { if (val & 1) omap2_dma_handle_ch(i); val >>= 1; @@ -1922,7 +1750,7 @@ static struct irqaction omap24xx_dma_irq; static struct lcd_dma_info { spinlock_t lock; int reserved; - void (*callback)(u16 status, void *data); + void (* callback)(u16 status, void *data); void *cb_data; int active; @@ -1944,7 +1772,6 @@ void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres, lcd_dma.xres = fb_xres; lcd_dma.yres = fb_yres; } -EXPORT_SYMBOL(omap_set_lcd_dma_b1); void omap_set_lcd_dma_src_port(int port) { @@ -1955,13 +1782,12 @@ void omap_set_lcd_dma_ext_controller(int external) { lcd_dma.ext_ctrl = external; } -EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); void omap_set_lcd_dma_single_transfer(int single) { lcd_dma.single_transfer = single; } -EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); + void omap_set_lcd_dma_b1_rotation(int rotate) { @@ -1972,7 +1798,6 @@ void omap_set_lcd_dma_b1_rotation(int rotate) } lcd_dma.rotate = rotate; } -EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation); void omap_set_lcd_dma_b1_mirror(int mirror) { @@ -1982,7 +1807,6 @@ void omap_set_lcd_dma_b1_mirror(int mirror) } lcd_dma.mirror = mirror; } -EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror); void omap_set_lcd_dma_b1_vxres(unsigned long vxres) { @@ -1993,7 +1817,6 @@ void omap_set_lcd_dma_b1_vxres(unsigned long vxres) } lcd_dma.vxres = vxres; } -EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres); void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) { @@ -2004,7 +1827,6 @@ void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale) lcd_dma.xscale = xscale; lcd_dma.yscale = yscale; } -EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale); static void set_b1_regs(void) { @@ -2035,11 +1857,8 @@ static void set_b1_regs(void) xscale = lcd_dma.xscale ? lcd_dma.xscale : 1; yscale = lcd_dma.yscale ? lcd_dma.yscale : 1; BUG_ON(vxres < lcd_dma.xres); - -#define PIXADDR(x, y) (lcd_dma.addr + \ - ((y) * vxres * yscale + (x) * xscale) * es) +#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es) #define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1) - switch (lcd_dma.rotate) { case 0: if (!lcd_dma.mirror) { @@ -2048,8 +1867,8 @@ static void set_b1_regs(void) /* 1510 DMA requires the bottom address to be 2 more * than the actual last memory access location. */ if (omap_dma_in_1510_mode() && - lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) - bottom += 2; + lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32) + bottom += 2; ei = PIXSTEP(0, 0, 1, 0); fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1); } else { @@ -2176,7 +1995,7 @@ static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -int omap_request_lcd_dma(void (*callback)(u16 status, void *data), +int omap_request_lcd_dma(void (* callback)(u16 status, void *data), void *data) { spin_lock_irq(&lcd_dma.lock); @@ -2202,7 +2021,6 @@ int omap_request_lcd_dma(void (*callback)(u16 status, void *data), return 0; } -EXPORT_SYMBOL(omap_request_lcd_dma); void omap_free_lcd_dma(void) { @@ -2219,14 +2037,12 @@ void omap_free_lcd_dma(void) lcd_dma.reserved = 0; spin_unlock(&lcd_dma.lock); } -EXPORT_SYMBOL(omap_free_lcd_dma); void omap_enable_lcd_dma(void) { u16 w; - /* - * Set the Enable bit only if an external controller is + /* Set the Enable bit only if an external controller is * connected. Otherwise the OMAP internal controller will * start the transfer when it gets enabled. */ @@ -2243,7 +2059,6 @@ void omap_enable_lcd_dma(void) w |= 1 << 7; omap_writew(w, OMAP1610_DMA_LCD_CCR); } -EXPORT_SYMBOL(omap_enable_lcd_dma); void omap_setup_lcd_dma(void) { @@ -2259,18 +2074,16 @@ void omap_setup_lcd_dma(void) u16 w; w = omap_readw(OMAP1610_DMA_LCD_CCR); - /* - * If DMA was already active set the end_prog bit to have + /* If DMA was already active set the end_prog bit to have * the programmed register set loaded into the active * register set. */ w |= 1 << 11; /* End_prog */ if (!lcd_dma.single_transfer) - w |= (3 << 8); /* Auto_init, repeat */ + w |= (3 << 8); /* Auto_init, repeat */ omap_writew(w, OMAP1610_DMA_LCD_CCR); } } -EXPORT_SYMBOL(omap_setup_lcd_dma); void omap_stop_lcd_dma(void) { @@ -2288,7 +2101,6 @@ void omap_stop_lcd_dma(void) w &= ~(1 << 8); omap_writew(w, OMAP1610_DMA_LCD_CTRL); } -EXPORT_SYMBOL(omap_stop_lcd_dma); /*----------------------------------------------------------------------------*/ @@ -2296,55 +2108,27 @@ static int __init omap_init_dma(void) { int ch, r; - if (cpu_class_is_omap1()) { - omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP1_DMA_BASE); - dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; - } else if (cpu_is_omap24xx()) { - omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP24XX_DMA4_BASE); - dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; - } else if (cpu_is_omap34xx()) { - omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP34XX_DMA4_BASE); - dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; - } else { - pr_err("DMA init failed for unsupported omap\n"); - return -ENODEV; - } - - dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count, - GFP_KERNEL); - if (!dma_chan) - return -ENOMEM; - - if (cpu_class_is_omap2()) { - dma_linked_lch = kzalloc(sizeof(struct dma_link_info) * - dma_lch_count, GFP_KERNEL); - if (!dma_linked_lch) { - kfree(dma_chan); - return -ENOMEM; - } - } - if (cpu_is_omap15xx()) { printk(KERN_INFO "DMA support for OMAP15xx initialized\n"); dma_chan_count = 9; enable_1510_mode = 1; } else if (cpu_is_omap16xx() || cpu_is_omap730()) { printk(KERN_INFO "OMAP DMA hardware version %d\n", - dma_read(HW_ID)); + omap_readw(OMAP_DMA_HW_ID)); printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", - (dma_read(CAPS_0_U) << 16) | - dma_read(CAPS_0_L), - (dma_read(CAPS_1_U) << 16) | - dma_read(CAPS_1_L), - dma_read(CAPS_2), dma_read(CAPS_3), - dma_read(CAPS_4)); + (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | + omap_readw(OMAP_DMA_CAPS_0_L), + (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | + omap_readw(OMAP_DMA_CAPS_1_L), + omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3), + omap_readw(OMAP_DMA_CAPS_4)); if (!enable_1510_mode) { u16 w; /* Disable OMAP 3.0/3.1 compatibility mode. */ - w = dma_read(GSCR); + w = omap_readw(OMAP_DMA_GSCR); w |= 1 << 3; - dma_write(w, GSCR); + omap_writew(w, OMAP_DMA_GSCR); dma_chan_count = 16; } else dma_chan_count = 9; @@ -2357,17 +2141,19 @@ static int __init omap_init_dma(void) omap_writew(w, OMAP1610_DMA_LCD_CTRL); } } else if (cpu_class_is_omap2()) { - u8 revision = dma_read(REVISION) & 0xff; + u8 revision = omap_readb(OMAP_DMA4_REVISION); printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", revision >> 4, revision & 0xf); - dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; + dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT; } else { dma_chan_count = 0; return 0; } + memset(&lcd_dma, 0, sizeof(lcd_dma)); spin_lock_init(&lcd_dma.lock); spin_lock_init(&dma_chan_lock); + memset(&dma_chan, 0, sizeof(dma_chan)); for (ch = 0; ch < dma_chan_count; ch++) { omap_clear_dma(ch); @@ -2378,10 +2164,8 @@ static int __init omap_init_dma(void) continue; if (cpu_class_is_omap1()) { - /* - * request_irq() doesn't like dev_id (ie. ch) being - * zero, so we have to kludge around this. - */ + /* request_irq() doesn't like dev_id (ie. ch) being + * zero, so we have to kludge around this. */ r = request_irq(omap1_dma_irq[ch], omap1_dma_irq_handler, 0, "DMA", (void *) (ch + 1)); @@ -2426,4 +2210,48 @@ static int __init omap_init_dma(void) arch_initcall(omap_init_dma); +EXPORT_SYMBOL(omap_get_dma_src_pos); +EXPORT_SYMBOL(omap_get_dma_dst_pos); +EXPORT_SYMBOL(omap_get_dma_src_addr_counter); +EXPORT_SYMBOL(omap_clear_dma); +EXPORT_SYMBOL(omap_set_dma_priority); +EXPORT_SYMBOL(omap_request_dma); +EXPORT_SYMBOL(omap_free_dma); +EXPORT_SYMBOL(omap_start_dma); +EXPORT_SYMBOL(omap_stop_dma); +EXPORT_SYMBOL(omap_set_dma_callback); +EXPORT_SYMBOL(omap_enable_dma_irq); +EXPORT_SYMBOL(omap_disable_dma_irq); + +EXPORT_SYMBOL(omap_set_dma_transfer_params); +EXPORT_SYMBOL(omap_set_dma_color_mode); +EXPORT_SYMBOL(omap_set_dma_write_mode); + +EXPORT_SYMBOL(omap_set_dma_src_params); +EXPORT_SYMBOL(omap_set_dma_src_index); +EXPORT_SYMBOL(omap_set_dma_src_data_pack); +EXPORT_SYMBOL(omap_set_dma_src_burst_mode); + +EXPORT_SYMBOL(omap_set_dma_dest_params); +EXPORT_SYMBOL(omap_set_dma_dest_index); +EXPORT_SYMBOL(omap_set_dma_dest_data_pack); +EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); + +EXPORT_SYMBOL(omap_set_dma_params); + +EXPORT_SYMBOL(omap_dma_link_lch); +EXPORT_SYMBOL(omap_dma_unlink_lch); + +EXPORT_SYMBOL(omap_request_lcd_dma); +EXPORT_SYMBOL(omap_free_lcd_dma); +EXPORT_SYMBOL(omap_enable_lcd_dma); +EXPORT_SYMBOL(omap_setup_lcd_dma); +EXPORT_SYMBOL(omap_stop_lcd_dma); +EXPORT_SYMBOL(omap_set_lcd_dma_b1); +EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer); +EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale); +EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror); diff --git a/trunk/arch/arm/plat-omap/dmtimer.c b/trunk/arch/arm/plat-omap/dmtimer.c index f22506af0e67..302ad8dff2cb 100644 --- a/trunk/arch/arm/plat-omap/dmtimer.c +++ b/trunk/arch/arm/plat-omap/dmtimer.c @@ -38,113 +38,34 @@ #include /* register offsets */ -#define _OMAP_TIMER_ID_OFFSET 0x00 -#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10 -#define _OMAP_TIMER_SYS_STAT_OFFSET 0x14 -#define _OMAP_TIMER_STAT_OFFSET 0x18 -#define _OMAP_TIMER_INT_EN_OFFSET 0x1c -#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20 -#define _OMAP_TIMER_CTRL_OFFSET 0x24 -#define OMAP_TIMER_CTRL_GPOCFG (1 << 14) -#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13) -#define OMAP_TIMER_CTRL_PT (1 << 12) -#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8) -#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8) -#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8) -#define OMAP_TIMER_CTRL_SCPWM (1 << 7) -#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */ -#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */ -#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* prescaler value shift */ -#define OMAP_TIMER_CTRL_POSTED (1 << 2) -#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */ -#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */ -#define _OMAP_TIMER_COUNTER_OFFSET 0x28 -#define _OMAP_TIMER_LOAD_OFFSET 0x2c -#define _OMAP_TIMER_TRIGGER_OFFSET 0x30 -#define _OMAP_TIMER_WRITE_PEND_OFFSET 0x34 -#define WP_NONE 0 /* no write pending bit */ -#define WP_TCLR (1 << 0) -#define WP_TCRR (1 << 1) -#define WP_TLDR (1 << 2) -#define WP_TTGR (1 << 3) -#define WP_TMAR (1 << 4) -#define WP_TPIR (1 << 5) -#define WP_TNIR (1 << 6) -#define WP_TCVR (1 << 7) -#define WP_TOCR (1 << 8) -#define WP_TOWR (1 << 9) -#define _OMAP_TIMER_MATCH_OFFSET 0x38 -#define _OMAP_TIMER_CAPTURE_OFFSET 0x3c -#define _OMAP_TIMER_IF_CTRL_OFFSET 0x40 -#define _OMAP_TIMER_CAPTURE2_OFFSET 0x44 /* TCAR2, 34xx only */ -#define _OMAP_TIMER_TICK_POS_OFFSET 0x48 /* TPIR, 34xx only */ -#define _OMAP_TIMER_TICK_NEG_OFFSET 0x4c /* TNIR, 34xx only */ -#define _OMAP_TIMER_TICK_COUNT_OFFSET 0x50 /* TCVR, 34xx only */ -#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET 0x54 /* TOCR, 34xx only */ -#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET 0x58 /* TOWR, 34xx only */ - -/* register offsets with the write pending bit encoded */ -#define WPSHIFT 16 - -#define OMAP_TIMER_ID_REG (_OMAP_TIMER_ID_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_OCP_CFG_REG (_OMAP_TIMER_OCP_CFG_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_SYS_STAT_REG (_OMAP_TIMER_SYS_STAT_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_STAT_REG (_OMAP_TIMER_STAT_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_INT_EN_REG (_OMAP_TIMER_INT_EN_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_CTRL_REG (_OMAP_TIMER_CTRL_OFFSET \ - | (WP_TCLR << WPSHIFT)) - -#define OMAP_TIMER_COUNTER_REG (_OMAP_TIMER_COUNTER_OFFSET \ - | (WP_TCRR << WPSHIFT)) - -#define OMAP_TIMER_LOAD_REG (_OMAP_TIMER_LOAD_OFFSET \ - | (WP_TLDR << WPSHIFT)) - -#define OMAP_TIMER_TRIGGER_REG (_OMAP_TIMER_TRIGGER_OFFSET \ - | (WP_TTGR << WPSHIFT)) - -#define OMAP_TIMER_WRITE_PEND_REG (_OMAP_TIMER_WRITE_PEND_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_MATCH_REG (_OMAP_TIMER_MATCH_OFFSET \ - | (WP_TMAR << WPSHIFT)) - -#define OMAP_TIMER_CAPTURE_REG (_OMAP_TIMER_CAPTURE_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_IF_CTRL_REG (_OMAP_TIMER_IF_CTRL_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_CAPTURE2_REG (_OMAP_TIMER_CAPTURE2_OFFSET \ - | (WP_NONE << WPSHIFT)) - -#define OMAP_TIMER_TICK_POS_REG (_OMAP_TIMER_TICK_POS_OFFSET \ - | (WP_TPIR << WPSHIFT)) - -#define OMAP_TIMER_TICK_NEG_REG (_OMAP_TIMER_TICK_NEG_OFFSET \ - | (WP_TNIR << WPSHIFT)) - -#define OMAP_TIMER_TICK_COUNT_REG (_OMAP_TIMER_TICK_COUNT_OFFSET \ - | (WP_TCVR << WPSHIFT)) - -#define OMAP_TIMER_TICK_INT_MASK_SET_REG \ - (_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT)) - -#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ - (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) +#define OMAP_TIMER_ID_REG 0x00 +#define OMAP_TIMER_OCP_CFG_REG 0x10 +#define OMAP_TIMER_SYS_STAT_REG 0x14 +#define OMAP_TIMER_STAT_REG 0x18 +#define OMAP_TIMER_INT_EN_REG 0x1c +#define OMAP_TIMER_WAKEUP_EN_REG 0x20 +#define OMAP_TIMER_CTRL_REG 0x24 +#define OMAP_TIMER_COUNTER_REG 0x28 +#define OMAP_TIMER_LOAD_REG 0x2c +#define OMAP_TIMER_TRIGGER_REG 0x30 +#define OMAP_TIMER_WRITE_PEND_REG 0x34 +#define OMAP_TIMER_MATCH_REG 0x38 +#define OMAP_TIMER_CAPTURE_REG 0x3c +#define OMAP_TIMER_IF_CTRL_REG 0x40 + +/* timer control reg bits */ +#define OMAP_TIMER_CTRL_GPOCFG (1 << 14) +#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13) +#define OMAP_TIMER_CTRL_PT (1 << 12) +#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8) +#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8) +#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8) +#define OMAP_TIMER_CTRL_SCPWM (1 << 7) +#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */ +#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */ +#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* how much to shift the prescaler value */ +#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */ +#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */ struct omap_dm_timer { unsigned long phys_base; @@ -155,7 +76,6 @@ struct omap_dm_timer { void __iomem *io_base; unsigned reserved:1; unsigned enabled:1; - unsigned posted:1; }; #ifdef CONFIG_ARCH_OMAP1 @@ -261,34 +181,16 @@ static struct clk **dm_source_clocks; static spinlock_t dm_timer_lock; -/* - * Reads timer registers in posted and non-posted mode. The posted mode bit - * is encoded in reg. Note that in posted mode write pending bit must be - * checked. Otherwise a read of a non completed write will produce an error. - */ -static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) +static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg) { - if (timer->posted) - while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff)) - & (reg >> WPSHIFT)) - cpu_relax(); - return readl(timer->io_base + (reg & 0xff)); + return readl(timer->io_base + reg); } -/* - * Writes timer registers in posted and non-posted mode. The posted mode bit - * is encoded in reg. Note that in posted mode the write pending bit must be - * checked. Otherwise a write on a register which has a pending write will be - * lost. - */ -static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, - u32 value) +static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value) { - if (timer->posted) - while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff)) - & (reg >> WPSHIFT)) - cpu_relax(); - writel(value, timer->io_base + (reg & 0xff)); + writel(value, timer->io_base + reg); + while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG)) + ; } static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) @@ -315,23 +217,17 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) } omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); + /* Set to smart-idle mode */ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); - l |= 0x02 << 3; /* Set to smart-idle mode */ - l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */ - - /* - * Enable wake-up only for GPT1 on OMAP2 CPUs. - * FIXME: All timers should have wake-up enabled and clear - * PRCM status. - */ - if (cpu_class_is_omap2() && (timer == &dm_timers[0])) + l |= 0x02 << 3; + + if (cpu_class_is_omap2() && timer == &dm_timers[0]) { + /* Enable wake-up only for GPT1 on OMAP2 CPUs*/ l |= 1 << 2; + /* Non-posted mode */ + omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0); + } omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); - - /* Match hardware reset default of posted mode */ - omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, - OMAP_TIMER_CTRL_POSTED); - timer->posted = 1; } static void omap_dm_timer_prepare(struct omap_dm_timer *timer) @@ -538,32 +434,9 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, l &= ~OMAP_TIMER_CTRL_AR; omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); - - /* REVISIT: hw feature, ttgr overtaking tldr? */ - while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))) - cpu_relax(); - omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); } -/* Optimized set_load which removes costly spin wait in timer_start */ -void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, - unsigned int load) -{ - u32 l; - - l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); - if (autoreload) - l |= OMAP_TIMER_CTRL_AR; - else - l &= ~OMAP_TIMER_CTRL_AR; - l |= OMAP_TIMER_CTRL_ST; - - omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load); - omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); - omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); -} - void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match) { @@ -578,6 +451,7 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); } + void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger) { diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index c7f74064696c..9cf83c4da9fa 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -15,66 +15,95 @@ #include #include #include -#include #include #include #include #include #include #include -#include + +#include +#include #include +#include +#include +#include #include -static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; +#ifdef CONFIG_MCBSP_DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +struct omap_mcbsp { + u32 io_base; + u8 id; + u8 free; + omap_mcbsp_word_length rx_word_length; + omap_mcbsp_word_length tx_word_length; + + omap_mcbsp_io_type_t io_type; /* IRQ or poll */ + /* IRQ based TX/RX */ + int rx_irq; + int tx_irq; + + /* DMA stuff */ + u8 dma_rx_sync; + short dma_rx_lch; + u8 dma_tx_sync; + short dma_tx_lch; + + /* Completion queues */ + struct completion tx_irq_completion; + struct completion rx_irq_completion; + struct completion tx_dma_completion; + struct completion rx_dma_completion; + + spinlock_t lock; +}; -#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \ - mcbsp[id].pdata->ops && \ - mcbsp[id].pdata->ops->check && \ - (mcbsp[id].pdata->ops->check(id) == 0)) +static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; +#ifdef CONFIG_ARCH_OMAP1 +static struct clk *mcbsp_dsp_ck = 0; +static struct clk *mcbsp_api_ck = 0; +static struct clk *mcbsp_dspxor_ck = 0; +#endif +#ifdef CONFIG_ARCH_OMAP2 +static struct clk *mcbsp1_ick = 0; +static struct clk *mcbsp1_fck = 0; +static struct clk *mcbsp2_ick = 0; +static struct clk *mcbsp2_fck = 0; +#endif static void omap_mcbsp_dump_reg(u8 id) { - dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id); - dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); - dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); - dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); - dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); - dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); - dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); - dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); - dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); - dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); - dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); - dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); - dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); - dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n", - OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); - dev_dbg(mcbsp[id].dev, "***********************\n"); + DBG("**** MCBSP%d regs ****\n", mcbsp[id].id); + DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); + DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); + DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); + DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); + DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); + DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); + DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); + DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); + DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); + DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); + DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); + DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); + DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); + DBG("***********************\n"); } static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) { struct omap_mcbsp *mcbsp_tx = dev_id; - dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); + DBG("TX IRQ callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); complete(&mcbsp_tx->tx_irq_completion); - return IRQ_HANDLED; } @@ -82,11 +111,10 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) { struct omap_mcbsp *mcbsp_rx = dev_id; - dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); + DBG("RX IRQ callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); complete(&mcbsp_rx->rx_irq_completion); - return IRQ_HANDLED; } @@ -94,8 +122,8 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) { struct omap_mcbsp *mcbsp_dma_tx = data; - dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); + DBG("TX DMA callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); /* We can free the channels */ omap_free_dma(mcbsp_dma_tx->dma_tx_lch); @@ -108,8 +136,8 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) { struct omap_mcbsp *mcbsp_dma_rx = data; - dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n", - OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); + DBG("RX DMA callback : 0x%x\n", + OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); /* We can free the channels */ omap_free_dma(mcbsp_dma_rx->dma_rx_lch); @@ -118,24 +146,19 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) complete(&mcbsp_dma_rx->rx_dma_completion); } + /* * omap_mcbsp_config simply write a config to the * appropriate McBSP. * You either call this function or set the McBSP registers * by yourself before calling omap_mcbsp_start(). */ -void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) -{ - u32 io_base; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return; - } +void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config) +{ + u32 io_base = mcbsp[id].io_base; - io_base = mcbsp[id].io_base; - dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n", - mcbsp[id].id, io_base); + DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base); /* We write the given config */ OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); @@ -150,7 +173,83 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); } -EXPORT_SYMBOL(omap_mcbsp_config); + + + +static int omap_mcbsp_check(unsigned int id) +{ + if (cpu_is_omap730()) { + if (id > OMAP_MAX_MCBSP_COUNT - 1) { + printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); + return -1; + } + return 0; + } + + if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { + if (id > OMAP_MAX_MCBSP_COUNT) { + printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); + return -1; + } + return 0; + } + + return -1; +} + +#ifdef CONFIG_ARCH_OMAP1 +static void omap_mcbsp_dsp_request(void) +{ + if (cpu_is_omap15xx() || cpu_is_omap16xx()) { + int ret; + + ret = omap_dsp_request_mem(); + if (ret < 0) { + printk(KERN_ERR "Could not get dsp memory: %i\n", ret); + return; + } + + clk_enable(mcbsp_dsp_ck); + clk_enable(mcbsp_api_ck); + + /* enable 12MHz clock to mcbsp 1 & 3 */ + clk_enable(mcbsp_dspxor_ck); + + /* + * DSP external peripheral reset + * FIXME: This should be moved to dsp code + */ + __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, + DSP_RSTCT2); + } +} + +static void omap_mcbsp_dsp_free(void) +{ + if (cpu_is_omap15xx() || cpu_is_omap16xx()) { + omap_dsp_release_mem(); + clk_disable(mcbsp_dspxor_ck); + clk_disable(mcbsp_dsp_ck); + clk_disable(mcbsp_api_ck); + } +} +#endif + +#ifdef CONFIG_ARCH_OMAP2 +static void omap2_mcbsp2_mux_setup(void) +{ + if (cpu_is_omap2420()) { + omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); + omap_cfg_reg(R14_24XX_MCBSP2_FSX); + omap_cfg_reg(W15_24XX_MCBSP2_DR); + omap_cfg_reg(V15_24XX_MCBSP2_DX); + omap_cfg_reg(V14_24XX_GPIO117); + } + /* + * Need to add MUX settings for OMAP 2430 SDP + */ +} +#endif /* * We can choose between IRQ based or polled IO. @@ -158,16 +257,13 @@ EXPORT_SYMBOL(omap_mcbsp_config); */ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) { - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } + if (omap_mcbsp_check(id) < 0) + return -EINVAL; spin_lock(&mcbsp[id].lock); if (!mcbsp[id].free) { - dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", - mcbsp[id].id); + printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); spin_unlock(&mcbsp[id].lock); return -EINVAL; } @@ -178,26 +274,38 @@ int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) return 0; } -EXPORT_SYMBOL(omap_mcbsp_set_io_type); int omap_mcbsp_request(unsigned int id) { int err; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } - - if (mcbsp[id].pdata->ops->request) - mcbsp[id].pdata->ops->request(id); + if (omap_mcbsp_check(id) < 0) + return -EINVAL; - clk_enable(mcbsp[id].clk); +#ifdef CONFIG_ARCH_OMAP1 + /* + * On 1510, 1610 and 1710, McBSP1 and McBSP3 + * are DSP public peripherals. + */ + if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) + omap_mcbsp_dsp_request(); +#endif + +#ifdef CONFIG_ARCH_OMAP2 + if (cpu_is_omap24xx()) { + if (id == OMAP_MCBSP1) { + clk_enable(mcbsp1_ick); + clk_enable(mcbsp1_fck); + } else { + clk_enable(mcbsp2_ick); + clk_enable(mcbsp2_fck); + } + } +#endif spin_lock(&mcbsp[id].lock); if (!mcbsp[id].free) { - dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", - mcbsp[id].id); + printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1); spin_unlock(&mcbsp[id].lock); return -1; } @@ -207,23 +315,24 @@ int omap_mcbsp_request(unsigned int id) if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { /* We need to get IRQs here */ - err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, - 0, "McBSP", (void *) (&mcbsp[id])); + err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); if (err != 0) { - dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d " - "for McBSP%d\n", mcbsp[id].tx_irq, - mcbsp[id].id); + printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n", + mcbsp[id].tx_irq, mcbsp[id].id); return err; } init_completion(&(mcbsp[id].tx_irq_completion)); - err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, - 0, "McBSP", (void *) (&mcbsp[id])); + + err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0, + "McBSP", + (void *) (&mcbsp[id])); if (err != 0) { - dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d " - "for McBSP%d\n", mcbsp[id].rx_irq, - mcbsp[id].id); + printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n", + mcbsp[id].rx_irq, mcbsp[id].id); free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); return err; } @@ -232,25 +341,36 @@ int omap_mcbsp_request(unsigned int id) } return 0; + } -EXPORT_SYMBOL(omap_mcbsp_request); void omap_mcbsp_free(unsigned int id) { - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + if (omap_mcbsp_check(id) < 0) return; - } - - if (mcbsp[id].pdata->ops->free) - mcbsp[id].pdata->ops->free(id); - clk_disable(mcbsp[id].clk); +#ifdef CONFIG_ARCH_OMAP1 + if (cpu_class_is_omap1()) { + if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) + omap_mcbsp_dsp_free(); + } +#endif + +#ifdef CONFIG_ARCH_OMAP2 + if (cpu_is_omap24xx()) { + if (id == OMAP_MCBSP1) { + clk_disable(mcbsp1_ick); + clk_disable(mcbsp1_fck); + } else { + clk_disable(mcbsp2_ick); + clk_disable(mcbsp2_fck); + } + } +#endif spin_lock(&mcbsp[id].lock); if (mcbsp[id].free) { - dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n", - mcbsp[id].id); + printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1); spin_unlock(&mcbsp[id].lock); return; } @@ -264,7 +384,6 @@ void omap_mcbsp_free(unsigned int id) free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); } } -EXPORT_SYMBOL(omap_mcbsp_free); /* * Here we start the McBSP, by enabling the sample @@ -276,15 +395,13 @@ void omap_mcbsp_start(unsigned int id) u32 io_base; u16 w; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + if (omap_mcbsp_check(id) < 0) return; - } io_base = mcbsp[id].io_base; - mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; - mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; + mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7); + mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7); /* Start the sample generator */ w = OMAP_MCBSP_READ(io_base, SPCR2); @@ -305,22 +422,20 @@ void omap_mcbsp_start(unsigned int id) /* Dump McBSP Regs */ omap_mcbsp_dump_reg(id); + } -EXPORT_SYMBOL(omap_mcbsp_start); void omap_mcbsp_stop(unsigned int id) { u32 io_base; u16 w; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + if (omap_mcbsp_check(id) < 0) return; - } io_base = mcbsp[id].io_base; - /* Reset transmitter */ + /* Reset transmitter */ w = OMAP_MCBSP_READ(io_base, SPCR2); OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); @@ -332,19 +447,12 @@ void omap_mcbsp_stop(unsigned int id) w = OMAP_MCBSP_READ(io_base, SPCR2); OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); } -EXPORT_SYMBOL(omap_mcbsp_stop); + /* polled mcbsp i/o operations */ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) { - u32 base; - - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } - - base = mcbsp[id].io_base; + u32 base = mcbsp[id].io_base; writew(buf, base + OMAP_MCBSP_REG_DXR1); /* if frame sync error - clear the error */ if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { @@ -366,27 +474,18 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) (XRST), base + OMAP_MCBSP_REG_SPCR2); udelay(10); - dev_err(mcbsp[id].dev, "Could not write to" - " McBSP%d Register\n", mcbsp[id].id); + printk(KERN_ERR + " Could not write to McBSP Register\n"); return -2; } } } - return 0; } -EXPORT_SYMBOL(omap_mcbsp_pollwrite); -int omap_mcbsp_pollread(unsigned int id, u16 *buf) +int omap_mcbsp_pollread(unsigned int id, u16 * buf) { - u32 base; - - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } - - base = mcbsp[id].io_base; + u32 base = mcbsp[id].io_base; /* if frame sync error - clear the error */ if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { /* clear error */ @@ -407,17 +506,15 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf) (RRST), base + OMAP_MCBSP_REG_SPCR1); udelay(10); - dev_err(mcbsp[id].dev, "Could not read from" - " McBSP%d Register\n", mcbsp[id].id); + printk(KERN_ERR + " Could not read from McBSP Register\n"); return -2; } } } *buf = readw(base + OMAP_MCBSP_REG_DRR1); - return 0; } -EXPORT_SYMBOL(omap_mcbsp_pollread); /* * IRQ based word transmission. @@ -425,15 +522,12 @@ EXPORT_SYMBOL(omap_mcbsp_pollread); void omap_mcbsp_xmit_word(unsigned int id, u32 word) { u32 io_base; - omap_mcbsp_word_length word_length; + omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + if (omap_mcbsp_check(id) < 0) return; - } io_base = mcbsp[id].io_base; - word_length = mcbsp[id].tx_word_length; wait_for_completion(&(mcbsp[id].tx_irq_completion)); @@ -441,20 +535,16 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word) OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); } -EXPORT_SYMBOL(omap_mcbsp_xmit_word); u32 omap_mcbsp_recv_word(unsigned int id) { u32 io_base; u16 word_lsb, word_msb = 0; - omap_mcbsp_word_length word_length; + omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } + if (omap_mcbsp_check(id) < 0) + return -EINVAL; - word_length = mcbsp[id].rx_word_length; io_base = mcbsp[id].io_base; wait_for_completion(&(mcbsp[id].rx_irq_completion)); @@ -465,24 +555,15 @@ u32 omap_mcbsp_recv_word(unsigned int id) return (word_lsb | (word_msb << 16)); } -EXPORT_SYMBOL(omap_mcbsp_recv_word); + int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) { - u32 io_base; - omap_mcbsp_word_length tx_word_length; - omap_mcbsp_word_length rx_word_length; + u32 io_base = mcbsp[id].io_base; + omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; + omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } - - io_base = mcbsp[id].io_base; - tx_word_length = mcbsp[id].tx_word_length; - rx_word_length = mcbsp[id].rx_word_length; - if (tx_word_length != rx_word_length) return -EINVAL; @@ -496,8 +577,7 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); udelay(10); - dev_err(mcbsp[id].dev, "McBSP%d transmitter not " - "ready\n", mcbsp[id].id); + printk("McBSP transmitter not ready\n"); return -EAGAIN; } } @@ -517,8 +597,7 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); udelay(10); - dev_err(mcbsp[id].dev, "McBSP%d receiver not " - "ready\n", mcbsp[id].id); + printk("McBSP receiver not ready\n"); return -EAGAIN; } } @@ -530,24 +609,14 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) return 0; } -EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); -int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) +int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word) { - u32 io_base, clock_word = 0; - omap_mcbsp_word_length tx_word_length; - omap_mcbsp_word_length rx_word_length; + u32 io_base = mcbsp[id].io_base, clock_word = 0; + omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; + omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } - - io_base = mcbsp[id].io_base; - tx_word_length = mcbsp[id].tx_word_length; - rx_word_length = mcbsp[id].rx_word_length; - if (tx_word_length != rx_word_length) return -EINVAL; @@ -561,8 +630,7 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); udelay(10); - dev_err(mcbsp[id].dev, "McBSP%d transmitter not " - "ready\n", mcbsp[id].id); + printk("McBSP transmitter not ready\n"); return -EAGAIN; } } @@ -582,8 +650,7 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) udelay(10); OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); udelay(10); - dev_err(mcbsp[id].dev, "McBSP%d receiver not " - "ready\n", mcbsp[id].id); + printk("McBSP receiver not ready\n"); return -EAGAIN; } } @@ -597,7 +664,7 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) return 0; } -EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); + /* * Simple DMA based buffer rx/tx routines. @@ -606,32 +673,25 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); * For anything fancier, you should use your own customized DMA * routines and callbacks. */ -int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, - unsigned int length) +int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { int dma_tx_ch; int src_port = 0; int dest_port = 0; int sync_dev = 0; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } + if (omap_mcbsp_check(id) < 0) + return -EINVAL; - if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", - omap_mcbsp_tx_dma_callback, - &mcbsp[id], - &dma_tx_ch)) { - dev_err(mcbsp[id].dev, " Unable to request DMA channel for " - "McBSP%d TX. Trying IRQ based TX\n", - mcbsp[id].id); + if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback, + &mcbsp[id], + &dma_tx_ch)) { + printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1); return -EAGAIN; } mcbsp[id].dma_tx_lch = dma_tx_ch; - dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id, - dma_tx_ch); + DBG("TX DMA on channel %d\n", dma_tx_ch); init_completion(&(mcbsp[id].tx_dma_completion)); @@ -639,7 +699,7 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, src_port = OMAP_DMA_PORT_TIPB; dest_port = OMAP_DMA_PORT_EMIFF; } - if (cpu_class_is_omap2()) + if (cpu_is_omap24xx()) sync_dev = mcbsp[id].dma_tx_sync; omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, @@ -662,37 +722,29 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, omap_start_dma(mcbsp[id].dma_tx_lch); wait_for_completion(&(mcbsp[id].tx_dma_completion)); - return 0; } -EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); -int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, - unsigned int length) + +int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length) { int dma_rx_ch; int src_port = 0; int dest_port = 0; int sync_dev = 0; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); - return -ENODEV; - } + if (omap_mcbsp_check(id) < 0) + return -EINVAL; - if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", - omap_mcbsp_rx_dma_callback, - &mcbsp[id], - &dma_rx_ch)) { - dev_err(mcbsp[id].dev, "Unable to request DMA channel for " - "McBSP%d RX. Trying IRQ based RX\n", - mcbsp[id].id); + if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback, + &mcbsp[id], + &dma_rx_ch)) { + printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1); return -EAGAIN; } mcbsp[id].dma_rx_lch = dma_rx_ch; - dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id, - dma_rx_ch); + DBG("RX DMA on channel %d\n", dma_rx_ch); init_completion(&(mcbsp[id].rx_dma_completion)); @@ -700,14 +752,14 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, src_port = OMAP_DMA_PORT_TIPB; dest_port = OMAP_DMA_PORT_EMIFF; } - if (cpu_class_is_omap2()) + if (cpu_is_omap24xx()) sync_dev = mcbsp[id].dma_rx_sync; omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, - OMAP_DMA_DATA_TYPE_S16, - length >> 1, 1, - OMAP_DMA_SYNC_ELEMENT, - sync_dev, 0); + OMAP_DMA_DATA_TYPE_S16, + length >> 1, 1, + OMAP_DMA_SYNC_ELEMENT, + sync_dev, 0); omap_set_dma_src_params(mcbsp[id].dma_rx_lch, src_port, @@ -716,17 +768,16 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, 0, 0); omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, - dest_port, - OMAP_DMA_AMODE_POST_INC, - buffer, - 0, 0); + dest_port, + OMAP_DMA_AMODE_POST_INC, + buffer, + 0, 0); omap_start_dma(mcbsp[id].dma_rx_lch); wait_for_completion(&(mcbsp[id].rx_dma_completion)); - return 0; } -EXPORT_SYMBOL(omap_mcbsp_recv_buffer); + /* * SPI wrapper. @@ -734,15 +785,12 @@ EXPORT_SYMBOL(omap_mcbsp_recv_buffer); * this wrapper just need an omap_mcbsp_spi_cfg structure as an input. * Once this is done, you can call omap_mcbsp_start(). */ -void omap_mcbsp_set_spi_mode(unsigned int id, - const struct omap_mcbsp_spi_cfg *spi_cfg) +void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg) { struct omap_mcbsp_reg_cfg mcbsp_cfg; - if (!omap_mcbsp_check_valid_id(id)) { - printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + if (omap_mcbsp_check(id) < 0) return; - } memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); @@ -750,7 +798,7 @@ void omap_mcbsp_set_spi_mode(unsigned int id, mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0)); mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0)); - /* Clock stop mode */ + /* Clock stop mode */ if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY) mcbsp_cfg.spcr1 |= (1 << 12); else @@ -779,12 +827,13 @@ void omap_mcbsp_set_spi_mode(unsigned int id, if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) { mcbsp_cfg.pcr0 |= CLKXM; - mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1); + mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1); mcbsp_cfg.pcr0 |= FSXM; mcbsp_cfg.srgr2 &= ~FSGM; mcbsp_cfg.xcr2 |= XDATDLY(1); mcbsp_cfg.rcr2 |= RDATDLY(1); - } else { + } + else { mcbsp_cfg.pcr0 &= ~CLKXM; mcbsp_cfg.srgr1 |= CLKGDV(1); mcbsp_cfg.pcr0 &= ~FSXM; @@ -797,99 +846,199 @@ void omap_mcbsp_set_spi_mode(unsigned int id, omap_mcbsp_config(id, &mcbsp_cfg); } -EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); + /* * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. * 730 has only 2 McBSP, and both of them are MPU peripherals. */ -static int __init omap_mcbsp_probe(struct platform_device *pdev) -{ - struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; - int id = pdev->id - 1; - int ret = 0; - - if (!pdata) { - dev_err(&pdev->dev, "McBSP device initialized without" - "platform data\n"); - ret = -EINVAL; - goto exit; - } - - dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); - - if (id >= OMAP_MAX_MCBSP_COUNT) { - dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); - ret = -EINVAL; - goto exit; - } +struct omap_mcbsp_info { + u32 virt_base; + u8 dma_rx_sync, dma_tx_sync; + u16 rx_irq, tx_irq; +}; - spin_lock_init(&mcbsp[id].lock); - mcbsp[id].id = id + 1; - mcbsp[id].free = 1; - mcbsp[id].dma_tx_lch = -1; - mcbsp[id].dma_rx_lch = -1; - - mcbsp[id].io_base = pdata->virt_base; - /* Default I/O is IRQ based */ - mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO; - mcbsp[id].tx_irq = pdata->tx_irq; - mcbsp[id].rx_irq = pdata->rx_irq; - mcbsp[id].dma_rx_sync = pdata->dma_rx_sync; - mcbsp[id].dma_tx_sync = pdata->dma_tx_sync; - - if (pdata->clk_name) - mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name); - if (IS_ERR(mcbsp[id].clk)) { - mcbsp[id].free = 0; - dev_err(&pdev->dev, - "Invalid clock configuration for McBSP%d.\n", - mcbsp[id].id); - ret = -EINVAL; - goto exit; - } - - mcbsp[id].pdata = pdata; - mcbsp[id].dev = &pdev->dev; - platform_set_drvdata(pdev, &mcbsp[id]); - -exit: - return ret; -} +#ifdef CONFIG_ARCH_OMAP730 +static const struct omap_mcbsp_info mcbsp_730[] = { + [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP_DMA_MCBSP1_TX, + .rx_irq = INT_730_McBSP1RX, + .tx_irq = INT_730_McBSP1TX }, + [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP3_RX, + .dma_tx_sync = OMAP_DMA_MCBSP3_TX, + .rx_irq = INT_730_McBSP2RX, + .tx_irq = INT_730_McBSP2TX }, +}; +#endif + +#ifdef CONFIG_ARCH_OMAP15XX +static const struct omap_mcbsp_info mcbsp_1510[] = { + [0] = { .virt_base = OMAP1510_MCBSP1_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP_DMA_MCBSP1_TX, + .rx_irq = INT_McBSP1RX, + .tx_irq = INT_McBSP1TX }, + [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP2_RX, + .dma_tx_sync = OMAP_DMA_MCBSP2_TX, + .rx_irq = INT_1510_SPI_RX, + .tx_irq = INT_1510_SPI_TX }, + [2] = { .virt_base = OMAP1510_MCBSP3_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP3_RX, + .dma_tx_sync = OMAP_DMA_MCBSP3_TX, + .rx_irq = INT_McBSP3RX, + .tx_irq = INT_McBSP3TX }, +}; +#endif + +#if defined(CONFIG_ARCH_OMAP16XX) +static const struct omap_mcbsp_info mcbsp_1610[] = { + [0] = { .virt_base = OMAP1610_MCBSP1_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP_DMA_MCBSP1_TX, + .rx_irq = INT_McBSP1RX, + .tx_irq = INT_McBSP1TX }, + [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE), + .dma_rx_sync = OMAP_DMA_MCBSP2_RX, + .dma_tx_sync = OMAP_DMA_MCBSP2_TX, + .rx_irq = INT_1610_McBSP2_RX, + .tx_irq = INT_1610_McBSP2_TX }, + [2] = { .virt_base = OMAP1610_MCBSP3_BASE, + .dma_rx_sync = OMAP_DMA_MCBSP3_RX, + .dma_tx_sync = OMAP_DMA_MCBSP3_TX, + .rx_irq = INT_McBSP3RX, + .tx_irq = INT_McBSP3TX }, +}; +#endif + +#if defined(CONFIG_ARCH_OMAP24XX) +static const struct omap_mcbsp_info mcbsp_24xx[] = { + [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), + .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, + .rx_irq = INT_24XX_MCBSP1_IRQ_RX, + .tx_irq = INT_24XX_MCBSP1_IRQ_TX, + }, + [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), + .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, + .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, + .rx_irq = INT_24XX_MCBSP2_IRQ_RX, + .tx_irq = INT_24XX_MCBSP2_IRQ_TX, + }, +}; +#endif -static int omap_mcbsp_remove(struct platform_device *pdev) +static int __init omap_mcbsp_init(void) { - struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - if (mcbsp) { + int mcbsp_count = 0, i; + static const struct omap_mcbsp_info *mcbsp_info; - if (mcbsp->pdata && mcbsp->pdata->ops && - mcbsp->pdata->ops->free) - mcbsp->pdata->ops->free(mcbsp->id); + printk("Initializing OMAP McBSP system\n"); - clk_disable(mcbsp->clk); - clk_put(mcbsp->clk); +#ifdef CONFIG_ARCH_OMAP1 + mcbsp_dsp_ck = clk_get(0, "dsp_ck"); + if (IS_ERR(mcbsp_dsp_ck)) { + printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); + return PTR_ERR(mcbsp_dsp_ck); + } + mcbsp_api_ck = clk_get(0, "api_ck"); + if (IS_ERR(mcbsp_api_ck)) { + printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n"); + return PTR_ERR(mcbsp_api_ck); + } + mcbsp_dspxor_ck = clk_get(0, "dspxor_ck"); + if (IS_ERR(mcbsp_dspxor_ck)) { + printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); + return PTR_ERR(mcbsp_dspxor_ck); + } +#endif +#ifdef CONFIG_ARCH_OMAP2 + mcbsp1_ick = clk_get(0, "mcbsp1_ick"); + if (IS_ERR(mcbsp1_ick)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n"); + return PTR_ERR(mcbsp1_ick); + } + mcbsp1_fck = clk_get(0, "mcbsp1_fck"); + if (IS_ERR(mcbsp1_fck)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n"); + return PTR_ERR(mcbsp1_fck); + } + mcbsp2_ick = clk_get(0, "mcbsp2_ick"); + if (IS_ERR(mcbsp2_ick)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n"); + return PTR_ERR(mcbsp2_ick); + } + mcbsp2_fck = clk_get(0, "mcbsp2_fck"); + if (IS_ERR(mcbsp2_fck)) { + printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n"); + return PTR_ERR(mcbsp2_fck); + } +#endif - mcbsp->clk = NULL; - mcbsp->free = 0; - mcbsp->dev = NULL; +#ifdef CONFIG_ARCH_OMAP730 + if (cpu_is_omap730()) { + mcbsp_info = mcbsp_730; + mcbsp_count = ARRAY_SIZE(mcbsp_730); + } +#endif +#ifdef CONFIG_ARCH_OMAP15XX + if (cpu_is_omap15xx()) { + mcbsp_info = mcbsp_1510; + mcbsp_count = ARRAY_SIZE(mcbsp_1510); + } +#endif +#if defined(CONFIG_ARCH_OMAP16XX) + if (cpu_is_omap16xx()) { + mcbsp_info = mcbsp_1610; + mcbsp_count = ARRAY_SIZE(mcbsp_1610); + } +#endif +#if defined(CONFIG_ARCH_OMAP24XX) + if (cpu_is_omap24xx()) { + mcbsp_info = mcbsp_24xx; + mcbsp_count = ARRAY_SIZE(mcbsp_24xx); + omap2_mcbsp2_mux_setup(); + } +#endif + for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { + if (i >= mcbsp_count) { + mcbsp[i].io_base = 0; + mcbsp[i].free = 0; + continue; + } + mcbsp[i].id = i + 1; + mcbsp[i].free = 1; + mcbsp[i].dma_tx_lch = -1; + mcbsp[i].dma_rx_lch = -1; + + mcbsp[i].io_base = mcbsp_info[i].virt_base; + mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */ + mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; + mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; + mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; + mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync; + spin_lock_init(&mcbsp[i].lock); } return 0; } -static struct platform_driver omap_mcbsp_driver = { - .probe = omap_mcbsp_probe, - .remove = omap_mcbsp_remove, - .driver = { - .name = "omap-mcbsp", - }, -}; - -int __init omap_mcbsp_init(void) -{ - /* Register the McBSP driver */ - return platform_driver_register(&omap_mcbsp_driver); -} +arch_initcall(omap_mcbsp_init); +EXPORT_SYMBOL(omap_mcbsp_config); +EXPORT_SYMBOL(omap_mcbsp_request); +EXPORT_SYMBOL(omap_mcbsp_set_io_type); +EXPORT_SYMBOL(omap_mcbsp_free); +EXPORT_SYMBOL(omap_mcbsp_start); +EXPORT_SYMBOL(omap_mcbsp_stop); +EXPORT_SYMBOL(omap_mcbsp_pollread); +EXPORT_SYMBOL(omap_mcbsp_pollwrite); +EXPORT_SYMBOL(omap_mcbsp_xmit_word); +EXPORT_SYMBOL(omap_mcbsp_recv_word); +EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); +EXPORT_SYMBOL(omap_mcbsp_recv_buffer); +EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); +EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); +EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); diff --git a/trunk/arch/arm/mach-omap1/sram.S b/trunk/arch/arm/plat-omap/sram-fn.S similarity index 92% rename from trunk/arch/arm/mach-omap1/sram.S rename to trunk/arch/arm/plat-omap/sram-fn.S index 126d252062d7..9e1813c77e05 100644 --- a/trunk/arch/arm/mach-omap1/sram.S +++ b/trunk/arch/arm/plat-omap/sram-fn.S @@ -18,7 +18,7 @@ /* * Reprograms ULPD and CKCTL. */ -ENTRY(omap1_sram_reprogram_clock) +ENTRY(sram_reprogram_clock) stmfd sp!, {r0 - r12, lr} @ save registers on stack mov r2, #IO_ADDRESS(DPLL_CTL) & 0xff000000 @@ -53,5 +53,5 @@ lock: ldrh r4, [r2], #0 @ read back dpll value out: ldmfd sp!, {r0 - r12, pc} @ restore regs and return -ENTRY(omap1_sram_reprogram_clock_sz) - .word . - omap1_sram_reprogram_clock +ENTRY(sram_reprogram_clock_sz) + .word . - sram_reprogram_clock diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index 554ee58e1294..1f23f0459e5f 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -10,7 +10,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#undef DEBUG #include #include @@ -25,43 +24,25 @@ #include #include -#include - -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -# include "../mach-omap2/prm.h" -# include "../mach-omap2/cm.h" -# include "../mach-omap2/sdrc.h" -#endif - #define OMAP1_SRAM_PA 0x20000000 -#define OMAP1_SRAM_VA VMALLOC_END +#define OMAP1_SRAM_VA 0xd0000000 #define OMAP2_SRAM_PA 0x40200000 #define OMAP2_SRAM_PUB_PA 0x4020f800 -#define OMAP2_SRAM_VA VMALLOC_END -#define OMAP2_SRAM_PUB_VA (VMALLOC_END + 0x800) -#define OMAP3_SRAM_PA 0x40200000 -#define OMAP3_SRAM_VA 0xd7000000 -#define OMAP3_SRAM_PUB_PA 0x40208000 -#define OMAP3_SRAM_PUB_VA 0xd7008000 - -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +#define OMAP2_SRAM_VA 0xd0000000 +#define OMAP2_SRAM_PUB_VA 0xd0000800 + +#if defined(CONFIG_ARCH_OMAP24XX) #define SRAM_BOOTLOADER_SZ 0x00 #else #define SRAM_BOOTLOADER_SZ 0x80 #endif -#define OMAP24XX_VA_REQINFOPERM0 IO_ADDRESS(0x68005048) -#define OMAP24XX_VA_READPERM0 IO_ADDRESS(0x68005050) -#define OMAP24XX_VA_WRITEPERM0 IO_ADDRESS(0x68005058) - -#define OMAP34XX_VA_REQINFOPERM0 IO_ADDRESS(0x68012848) -#define OMAP34XX_VA_READPERM0 IO_ADDRESS(0x68012850) -#define OMAP34XX_VA_WRITEPERM0 IO_ADDRESS(0x68012858) -#define OMAP34XX_VA_ADDR_MATCH2 IO_ADDRESS(0x68012880) -#define OMAP34XX_VA_SMS_RG_ATT0 IO_ADDRESS(0x6C000048) -#define OMAP34XX_VA_CONTROL_STAT IO_ADDRESS(0x480022F0) - +#define VA_REQINFOPERM0 IO_ADDRESS(0x68005048) +#define VA_READPERM0 IO_ADDRESS(0x68005050) +#define VA_WRITEPERM0 IO_ADDRESS(0x68005058) +#define VA_CONTROL_STAT IO_ADDRESS(0x480002F8) #define GP_DEVICE 0x300 +#define TYPE_MASK 0x700 #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) @@ -87,21 +68,14 @@ static int is_sram_locked(void) int type = 0; if (cpu_is_omap242x()) - type = system_rev & OMAP2_DEVICETYPE_MASK; + type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK; if (type == GP_DEVICE) { /* RAMFW: R/W access to all initiators for all qualifier sets */ if (cpu_is_omap242x()) { - __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */ - __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ - __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ - } - if (cpu_is_omap34xx()) { - __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ - __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ - __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ - __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2); - __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0); + __raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */ + __raw_writel(0xCFDE, VA_READPERM0); /* all i-read */ + __raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */ } return 0; } else @@ -118,30 +92,18 @@ void __init omap_detect_sram(void) { unsigned long reserved; - if (cpu_class_is_omap2()) { + if (cpu_is_omap24xx()) { if (is_sram_locked()) { - if (cpu_is_omap34xx()) { - omap_sram_base = OMAP3_SRAM_PUB_VA; - omap_sram_start = OMAP3_SRAM_PUB_PA; - omap_sram_size = 0x8000; /* 32K */ - } else { - omap_sram_base = OMAP2_SRAM_PUB_VA; - omap_sram_start = OMAP2_SRAM_PUB_PA; - omap_sram_size = 0x800; /* 2K */ - } + omap_sram_base = OMAP2_SRAM_PUB_VA; + omap_sram_start = OMAP2_SRAM_PUB_PA; + omap_sram_size = 0x800; /* 2K */ } else { - if (cpu_is_omap34xx()) { - omap_sram_base = OMAP3_SRAM_VA; - omap_sram_start = OMAP3_SRAM_PA; + omap_sram_base = OMAP2_SRAM_VA; + omap_sram_start = OMAP2_SRAM_PA; + if (cpu_is_omap242x()) + omap_sram_size = 0xa0000; /* 640K */ + else if (cpu_is_omap243x()) omap_sram_size = 0x10000; /* 64K */ - } else { - omap_sram_base = OMAP2_SRAM_VA; - omap_sram_start = OMAP2_SRAM_PA; - if (cpu_is_omap242x()) - omap_sram_size = 0xa0000; /* 640K */ - else if (cpu_is_omap243x()) - omap_sram_size = 0x10000; /* 64K */ - } } } else { omap_sram_base = OMAP1_SRAM_VA; @@ -195,13 +157,6 @@ void __init omap_map_sram(void) omap_sram_io_desc[0].pfn = __phys_to_pfn(base); } - if (cpu_is_omap34xx()) { - omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA; - base = OMAP3_SRAM_PA; - base = ROUND_DOWN(base, PAGE_SIZE); - omap_sram_io_desc[0].pfn = __phys_to_pfn(base); - } - omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */ iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); @@ -236,7 +191,6 @@ void * omap_sram_push(void * start, unsigned long size) omap_sram_ceil -= size; omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); memcpy((void *)omap_sram_ceil, start, size); - flush_icache_range((unsigned long)start, (unsigned long)(start + size)); return (void *)omap_sram_ceil; } @@ -260,9 +214,8 @@ void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) int __init omap1_sram_init(void) { - _omap_sram_reprogram_clock = - omap_sram_push(omap1_sram_reprogram_clock, - omap1_sram_reprogram_clock_sz); + _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock, + sram_reprogram_clock_sz); return 0; } @@ -271,7 +224,7 @@ int __init omap1_sram_init(void) #define omap1_sram_init() do {} while (0) #endif -#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) +#ifdef CONFIG_ARCH_OMAP2 static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, u32 base_cs, u32 force_unlock); @@ -306,109 +259,19 @@ u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); } -#endif - -#ifdef CONFIG_ARCH_OMAP2420 -int __init omap242x_sram_init(void) -{ - _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init, - omap242x_sram_ddr_init_sz); - - _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc, - omap242x_sram_reprogram_sdrc_sz); - - _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm, - omap242x_sram_set_prcm_sz); - - return 0; -} -#else -static inline int omap242x_sram_init(void) -{ - return 0; -} -#endif - -#ifdef CONFIG_ARCH_OMAP2430 -int __init omap243x_sram_init(void) -{ - _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init, - omap243x_sram_ddr_init_sz); - - _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc, - omap243x_sram_reprogram_sdrc_sz); - - _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm, - omap243x_sram_set_prcm_sz); - - return 0; -} -#else -static inline int omap243x_sram_init(void) -{ - return 0; -} -#endif - -#ifdef CONFIG_ARCH_OMAP3 - -static u32 (*_omap2_sram_reprogram_gpmc)(u32 perf_level); -u32 omap2_sram_reprogram_gpmc(u32 perf_level) -{ - if (!_omap2_sram_reprogram_gpmc) - omap_sram_error(); - - return _omap2_sram_reprogram_gpmc(perf_level); -} - -static u32 (*_omap2_sram_configure_core_dpll)(u32 m, u32 n, - u32 freqsel, u32 m2); -u32 omap2_sram_configure_core_dpll(u32 m, u32 n, u32 freqsel, u32 m2) -{ - if (!_omap2_sram_configure_core_dpll) - omap_sram_error(); - - return _omap2_sram_configure_core_dpll(m, n, freqsel, m2); -} -/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */ -void restore_sram_functions(void) +int __init omap2_sram_init(void) { - omap_sram_ceil = omap_sram_base + omap_sram_size; + _omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz); - _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc, - omap34xx_sram_reprogram_gpmc_sz); - - _omap2_sram_configure_core_dpll = - omap_sram_push(omap34xx_sram_configure_core_dpll, - omap34xx_sram_configure_core_dpll_sz); -} - -int __init omap34xx_sram_init(void) -{ - _omap2_sram_ddr_init = omap_sram_push(omap34xx_sram_ddr_init, - omap34xx_sram_ddr_init_sz); - - _omap2_sram_reprogram_sdrc = omap_sram_push(omap34xx_sram_reprogram_sdrc, - omap34xx_sram_reprogram_sdrc_sz); - - _omap2_set_prcm = omap_sram_push(omap34xx_sram_set_prcm, - omap34xx_sram_set_prcm_sz); - - _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc, - omap34xx_sram_reprogram_gpmc_sz); - - _omap2_sram_configure_core_dpll = - omap_sram_push(omap34xx_sram_configure_core_dpll, - omap34xx_sram_configure_core_dpll_sz); + _omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc, + sram_reprogram_sdrc_sz); + _omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz); return 0; } #else -static inline int omap34xx_sram_init(void) -{ - return 0; -} +#define omap2_sram_init() do {} while (0) #endif int __init omap_sram_init(void) @@ -416,14 +279,10 @@ int __init omap_sram_init(void) omap_detect_sram(); omap_map_sram(); - if (!(cpu_class_is_omap2())) + if (!cpu_is_omap24xx()) omap1_sram_init(); - else if (cpu_is_omap242x()) - omap242x_sram_init(); - else if (cpu_is_omap2430()) - omap243x_sram_init(); - else if (cpu_is_omap34xx()) - omap34xx_sram_init(); + else + omap2_sram_init(); return 0; } diff --git a/trunk/arch/arm/plat-omap/usb.c b/trunk/arch/arm/plat-omap/usb.c index 2699c16d4da0..a619475c4b76 100644 --- a/trunk/arch/arm/plat-omap/usb.c +++ b/trunk/arch/arm/plat-omap/usb.c @@ -1,4 +1,4 @@ - /* +/* * arch/arm/plat-omap/usb.c -- platform level USB initialization * * Copyright (C) 2004 Texas Instruments, Inc. @@ -156,12 +156,8 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) if (nwires == 0) { if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { - u32 l; - /* pulldown D+/D- */ - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~(3 << 1); - omap_writel(l, USB_TRANSCEIVER_CTRL); + USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1); } return 0; } @@ -175,8 +171,6 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) /* internal transceiver (unavailable on 17xx, 24xx) */ if (!cpu_class_is_omap2() && nwires == 2) { - u32 l; - // omap_cfg_reg(P9_USB_DP); // omap_cfg_reg(R8_USB_DM); @@ -191,11 +185,9 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) * - OTG support on this port not yet written */ - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~(7 << 4); + USB_TRANSCEIVER_CTRL_REG &= ~(7 << 4); if (!is_device) - l |= (3 << 1); - omap_writel(l, USB_TRANSCEIVER_CTRL); + USB_TRANSCEIVER_CTRL_REG |= (3 << 1); return 3 << 16; } @@ -225,13 +217,8 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) * with VBUS switching and overcurrent detection. */ - if (cpu_class_is_omap1() && nwires != 6) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } + if (cpu_class_is_omap1() && nwires != 6) + USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; switch (nwires) { case 3: @@ -251,13 +238,9 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) omap_cfg_reg(K20_24XX_USB0_VM); omap2_usb_devconf_set(0, USB_UNIDIR); } else { - u32 l; - omap_cfg_reg(AA9_USB0_VP); omap_cfg_reg(R9_USB0_VM); - l = omap_readl(USB_TRANSCEIVER_CTRL); - l |= CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); + USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; } break; default: @@ -271,13 +254,8 @@ static u32 __init omap_usb1_init(unsigned nwires) { u32 syscon1 = 0; - if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~CONF_USB1_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } + if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) + USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R; if (cpu_is_omap24xx()) omap2_usb_devconf_clear(1, USB_BIDIR_TLL); @@ -338,13 +316,8 @@ static u32 __init omap_usb1_init(unsigned nwires) syscon1 = 3; omap_cfg_reg(USB1_VP); omap_cfg_reg(USB1_VM); - if (!cpu_is_omap15xx()) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l |= CONF_USB1_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } + if (!cpu_is_omap15xx()) + USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R; break; default: bad: @@ -367,13 +340,8 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) if (alt_pingroup || nwires == 0) return 0; - if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } + if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) + USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R; /* external transceiver */ if (cpu_is_omap15xx()) { @@ -442,13 +410,9 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) omap_cfg_reg(USB2_VP); omap_cfg_reg(USB2_VM); } else { - u32 l; - omap_cfg_reg(AA9_USB2_VP); omap_cfg_reg(R9_USB2_VM); - l = omap_readl(USB_TRANSCEIVER_CTRL); - l |= CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); + USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R; } break; default: @@ -567,6 +531,10 @@ static struct platform_device otg_device = { /*-------------------------------------------------------------------------*/ +#define ULPD_CLOCK_CTRL_REG __REG16(ULPD_CLOCK_CTRL) +#define ULPD_SOFT_REQ_REG __REG16(ULPD_SOFT_REQ) + + // FIXME correct answer depends on hmc_mode, // as does (on omap1) any nonzero value for config->otg port number #ifdef CONFIG_USB_GADGET_OMAP @@ -582,17 +550,17 @@ static struct platform_device otg_device = { void __init omap_otg_init(struct omap_usb_config *config) { - u32 syscon; + u32 syscon = OTG_SYSCON_1_REG & 0xffff; int status; int alt_pingroup = 0; /* NOTE: no bus or clock setup (yet?) */ - syscon = omap_readl(OTG_SYSCON_1) & 0xffff; + syscon = OTG_SYSCON_1_REG & 0xffff; if (!(syscon & OTG_RESET_DONE)) pr_debug("USB resets not complete?\n"); - //omap_writew(0, OTG_IRQ_EN); + // OTG_IRQ_EN_REG = 0; /* pin muxing and transceiver pinouts */ if (config->pins[0] > 2) /* alt pingroup 2 */ @@ -600,8 +568,8 @@ omap_otg_init(struct omap_usb_config *config) syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config)); syscon |= omap_usb1_init(config->pins[1]); syscon |= omap_usb2_init(config->pins[2], alt_pingroup); - pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); - omap_writel(syscon, OTG_SYSCON_1); + pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon); + OTG_SYSCON_1_REG = syscon; syscon = config->hmc_mode; syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; @@ -610,10 +578,9 @@ omap_otg_init(struct omap_usb_config *config) syscon |= OTG_EN; #endif if (cpu_class_is_omap1()) - pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", - omap_readl(USB_TRANSCEIVER_CTRL)); - pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); - omap_writel(syscon, OTG_SYSCON_2); + pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG); + pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon); + OTG_SYSCON_2_REG = syscon; printk("USB: hmc %d", config->hmc_mode); if (!alt_pingroup) @@ -630,19 +597,12 @@ omap_otg_init(struct omap_usb_config *config) printk("\n"); if (cpu_class_is_omap1()) { - u16 w; - /* leave USB clocks/controllers off until needed */ - w = omap_readw(ULPD_SOFT_REQ); - w &= ~SOFT_USB_CLK_REQ; - omap_writew(w, ULPD_SOFT_REQ); - - w = omap_readw(ULPD_CLOCK_CTRL); - w &= ~USB_MCLK_EN; - w |= DIS_USB_PVCI_CLK; - omap_writew(w, ULPD_CLOCK_CTRL); + ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ; + ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN; + ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK; } - syscon = omap_readl(OTG_SYSCON_1); + syscon = OTG_SYSCON_1_REG; syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; #ifdef CONFIG_USB_GADGET_OMAP @@ -679,8 +639,8 @@ omap_otg_init(struct omap_usb_config *config) pr_debug("can't register OTG device, %d\n", status); } #endif - pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); - omap_writel(syscon, OTG_SYSCON_1); + pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon); + OTG_SYSCON_1_REG = syscon; status = 0; } @@ -693,19 +653,18 @@ static inline void omap_otg_init(struct omap_usb_config *config) {} #ifdef CONFIG_ARCH_OMAP15XX -/* ULPD_DPLL_CTRL */ +#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL) #define DPLL_IOB (1 << 13) #define DPLL_PLL_ENABLE (1 << 4) #define DPLL_LOCK (1 << 0) -/* ULPD_APLL_CTRL */ +#define ULPD_APLL_CTRL_REG __REG16(ULPD_APLL_CTRL) #define APLL_NDPLL_SWITCH (1 << 0) static void __init omap_1510_usb_init(struct omap_usb_config *config) { unsigned int val; - u16 w; omap_usb0_init(config->pins[0], is_usb0_device(config)); omap_usb1_init(config->pins[1]); @@ -726,22 +685,12 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) printk("\n"); /* use DPLL for 48 MHz function clock */ - pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL), - omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ)); - - w = omap_readw(ULPD_APLL_CTRL); - w &= ~APLL_NDPLL_SWITCH; - omap_writew(w, ULPD_APLL_CTRL); - - w = omap_readw(ULPD_DPLL_CTRL); - w |= DPLL_IOB | DPLL_PLL_ENABLE; - omap_writew(w, ULPD_DPLL_CTRL); - - w = omap_readw(ULPD_SOFT_REQ); - w |= SOFT_UDC_REQ | SOFT_DPLL_REQ; - omap_writew(w, ULPD_SOFT_REQ); - - while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK)) + pr_debug("APLL %04x DPLL %04x REQ %04x\n", ULPD_APLL_CTRL_REG, + ULPD_DPLL_CTRL_REG, ULPD_SOFT_REQ_REG); + ULPD_APLL_CTRL_REG &= ~APLL_NDPLL_SWITCH; + ULPD_DPLL_CTRL_REG |= DPLL_IOB | DPLL_PLL_ENABLE; + ULPD_SOFT_REQ_REG |= SOFT_UDC_REQ | SOFT_DPLL_REQ; + while (!(ULPD_DPLL_CTRL_REG & DPLL_LOCK)) cpu_relax(); #ifdef CONFIG_USB_GADGET_OMAP diff --git a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 6be0c50122e8..917325bfbd84 100644 --- a/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/trunk/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -254,8 +254,7 @@ close_cplbtab(struct cplb_tab *table) } /* helper function */ -static void __init -__fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) +static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) { if (cplb_data[i].psize) { fill_cplbtab(t, @@ -292,8 +291,7 @@ __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) } } -static void __init -__fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) +static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) { if (cplb_data[i].psize) { fill_cplbtab(t, diff --git a/trunk/arch/blackfin/kernel/irqchip.c b/trunk/arch/blackfin/kernel/irqchip.c index 07402f57c9de..73647c158774 100644 --- a/trunk/arch/blackfin/kernel/irqchip.c +++ b/trunk/arch/blackfin/kernel/irqchip.c @@ -60,14 +60,9 @@ static struct irq_chip bad_chip = { }; static struct irq_desc bad_irq_desc = { - .status = IRQ_DISABLED, .chip = &bad_chip, .handle_irq = handle_bad_irq, .depth = 1, - .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), -#ifdef CONFIG_SMP - .affinity = CPU_MASK_ALL -#endif }; int show_interrupts(struct seq_file *p, void *v) diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index 39752cdef6ff..082c31dcfd99 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -558,6 +558,8 @@ static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void) if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) { rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES); + if (!rte) + return NULL; for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++) list_add(&rte->rte_list, &free_rte_list); } diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index 632cda8f2e76..f48a809c686d 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -547,8 +547,7 @@ setup_arch (char **cmdline_p) # ifdef CONFIG_ACPI_NUMA acpi_numa_init(); per_cpu_scan_finalize((cpus_weight(early_cpu_possible_map) == 0 ? - 32 : cpus_weight(early_cpu_possible_map)), - additional_cpus > 0 ? additional_cpus : 0); + 32 : cpus_weight(early_cpu_possible_map)), additional_cpus); # endif #else # ifdef CONFIG_SMP @@ -579,6 +578,8 @@ setup_arch (char **cmdline_p) cpu_init(); /* initialize the bootstrap CPU */ mmu_context_init(); /* initialize context_id bitmap */ + check_sal_cache_flush(); + #ifdef CONFIG_ACPI acpi_boot_init(); #endif @@ -606,7 +607,6 @@ setup_arch (char **cmdline_p) ia64_mca_init(); platform_setup(cmdline_p); - check_sal_cache_flush(); paging_init(); } diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index aad1b7b1fff9..8c73643f2d66 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -117,7 +117,6 @@ void account_system_vtime(struct task_struct *tsk) local_irq_restore(flags); } -EXPORT_SYMBOL_GPL(account_system_vtime); /* * Called from the timer interrupt handler to charge accumulated user time diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c index e585f9a2afb9..49d3120415eb 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -512,8 +512,6 @@ static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, si int cpu; char optstr[64]; - if (count == 0 || count > sizeof(optstr)) - return -EINVAL; if (copy_from_user(optstr, user, count)) return -EFAULT; optstr[count - 1] = '\0'; diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 095e04db1c0e..1cee2f9fdf06 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -273,8 +273,7 @@ endif initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-)) initrd-y := $(patsubst zImage%, zImage.initrd%, \ $(patsubst dtbImage%, dtbImage.initrd%, \ - $(patsubst simpleImage%, simpleImage.initrd%, \ - $(patsubst treeImage%, treeImage.initrd%, $(image-y))))) + $(patsubst treeImage%, treeImage.initrd%, $(image-y)))) initrd-y := $(filter-out $(image-y), $(initrd-y)) targets += $(image-y) $(initrd-y) diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c index cf37f5ca4b71..61dd17449ddc 100644 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ b/trunk/arch/powerpc/kernel/legacy_serial.c @@ -136,11 +136,6 @@ static int __init add_legacy_soc_port(struct device_node *np, if (of_get_property(np, "clock-frequency", NULL) == NULL) return -1; - /* if reg-shift or offset, don't try to use it */ - if ((of_get_property(np, "reg-shift", NULL) != NULL) || - (of_get_property(np, "reg-offset", NULL) != NULL)) - return -1; - /* if rtas uses this device, don't try to use it as well */ if (of_get_property(np, "used-by-rtas", NULL) != NULL) return -1; diff --git a/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c b/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c index fe92e65103ed..41c7fd91e99e 100644 --- a/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c @@ -14,7 +14,6 @@ static struct mpc52xx_sdma __iomem *bes; static struct mpc52xx_xlb __iomem *xlb; static struct mpc52xx_gpio __iomem *gps; static struct mpc52xx_gpio_wkup __iomem *gpw; -static void __iomem *pci; static void __iomem *sram; static const int sram_size = 0x4000; /* 16 kBytes */ static void __iomem *mbar; @@ -51,8 +50,6 @@ static int lite5200_pm_prepare(void) { .type = "builtin", .compatible = "mpc5200", }, /* efika */ {} }; - u64 regaddr64 = 0; - const u32 *regaddr_p; /* deep sleep? let mpc52xx code handle that */ if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) @@ -63,12 +60,8 @@ static int lite5200_pm_prepare(void) /* map registers */ np = of_find_matching_node(NULL, immr_ids); - regaddr_p = of_get_address(np, 0, NULL, NULL); - if (regaddr_p) - regaddr64 = of_translate_address(np, regaddr_p); + mbar = of_iomap(np, 0); of_node_put(np); - - mbar = ioremap((u32) regaddr64, 0xC000); if (!mbar) { printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); return -ENOSYS; @@ -78,7 +71,6 @@ static int lite5200_pm_prepare(void) pic = mbar + 0x500; gps = mbar + 0xb00; gpw = mbar + 0xc00; - pci = mbar + 0xd00; bes = mbar + 0x1200; xlb = mbar + 0x1f00; sram = mbar + 0x8000; @@ -93,7 +85,6 @@ static struct mpc52xx_sdma sbes; static struct mpc52xx_xlb sxlb; static struct mpc52xx_gpio sgps; static struct mpc52xx_gpio_wkup sgpw; -static char spci[0x200]; static void lite5200_save_regs(void) { @@ -103,7 +94,6 @@ static void lite5200_save_regs(void) _memcpy_fromio(&sxlb, xlb, sizeof(*xlb)); _memcpy_fromio(&sgps, gps, sizeof(*gps)); _memcpy_fromio(&sgpw, gpw, sizeof(*gpw)); - _memcpy_fromio(spci, pci, 0x200); _memcpy_fromio(saved_sram, sram, sram_size); } @@ -113,8 +103,6 @@ static void lite5200_restore_regs(void) int i; _memcpy_toio(sram, saved_sram, sram_size); - /* PCI Configuration */ - _memcpy_toio(pci, spci, 0x200); /* * GPIOs. Interrupt Master Enable has higher address then other diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index bf07b6f50fa1..52e18e6d2ba0 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -383,7 +383,6 @@ config VMI config KVM_CLOCK bool "KVM paravirtualized clock" select PARAVIRT - select PARAVIRT_CLOCK depends on !(X86_VISWS || X86_VOYAGER) help Turning on this option will allow you to run a paravirtualized clock @@ -411,10 +410,6 @@ config PARAVIRT over full virtualization. However, when run without a hypervisor the kernel is theoretically slower and slightly larger. -config PARAVIRT_CLOCK - bool - default n - endif config MEMTEST_BOOTPARAM @@ -966,8 +961,8 @@ config NUMA_EMU number of nodes. This is only useful for debugging. config NODES_SHIFT - int "Max num nodes shift(1-9)" - range 1 9 if X86_64 + int "Max num nodes shift(1-15)" + range 1 15 if X86_64 default "6" if X86_64 default "4" if X86_NUMAQ default "3" diff --git a/trunk/arch/x86/kernel/Makefile b/trunk/arch/x86/kernel/Makefile index 77807d4769c9..5e618c3b4720 100644 --- a/trunk/arch/x86/kernel/Makefile +++ b/trunk/arch/x86/kernel/Makefile @@ -82,7 +82,6 @@ obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o obj-$(CONFIG_KVM_GUEST) += kvm.o obj-$(CONFIG_KVM_CLOCK) += kvmclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o -obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c index 95e80e5033c3..eb9ddd8efb82 100644 --- a/trunk/arch/x86/kernel/i387.c +++ b/trunk/arch/x86/kernel/i387.c @@ -162,7 +162,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, int ret; if (!cpu_has_fxsr) - return -EIO; + return -ENODEV; ret = init_fpu(target); if (ret) @@ -179,7 +179,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, int ret; if (!cpu_has_fxsr) - return -EIO; + return -ENODEV; ret = init_fpu(target); if (ret) diff --git a/trunk/arch/x86/kernel/kvmclock.c b/trunk/arch/x86/kernel/kvmclock.c index 87edf1ceb1df..08a30986d472 100644 --- a/trunk/arch/x86/kernel/kvmclock.c +++ b/trunk/arch/x86/kernel/kvmclock.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -37,9 +36,18 @@ static int parse_no_kvmclock(char *arg) early_param("no-kvmclock", parse_no_kvmclock); /* The hypervisor will put information about time periodically here */ -static DEFINE_PER_CPU_SHARED_ALIGNED(struct pvclock_vcpu_time_info, hv_clock); -static struct pvclock_wall_clock wall_clock; +static DEFINE_PER_CPU_SHARED_ALIGNED(struct kvm_vcpu_time_info, hv_clock); +#define get_clock(cpu, field) per_cpu(hv_clock, cpu).field +static inline u64 kvm_get_delta(u64 last_tsc) +{ + int cpu = smp_processor_id(); + u64 delta = native_read_tsc() - last_tsc; + return (delta * get_clock(cpu, tsc_to_system_mul)) >> KVM_SCALE; +} + +static struct kvm_wall_clock wall_clock; +static cycle_t kvm_clock_read(void); /* * The wallclock is the time of day when we booted. Since then, some time may * have elapsed since the hypervisor wrote the data. So we try to account for @@ -47,37 +55,64 @@ static struct pvclock_wall_clock wall_clock; */ static unsigned long kvm_get_wallclock(void) { - struct pvclock_vcpu_time_info *vcpu_time; + u32 wc_sec, wc_nsec; + u64 delta; struct timespec ts; + int version, nsec; int low, high; low = (int)__pa(&wall_clock); high = ((u64)__pa(&wall_clock) >> 32); - native_write_msr(MSR_KVM_WALL_CLOCK, low, high); - vcpu_time = &get_cpu_var(hv_clock); - pvclock_read_wallclock(&wall_clock, vcpu_time, &ts); - put_cpu_var(hv_clock); + delta = kvm_clock_read(); - return ts.tv_sec; + native_write_msr(MSR_KVM_WALL_CLOCK, low, high); + do { + version = wall_clock.wc_version; + rmb(); + wc_sec = wall_clock.wc_sec; + wc_nsec = wall_clock.wc_nsec; + rmb(); + } while ((wall_clock.wc_version != version) || (version & 1)); + + delta = kvm_clock_read() - delta; + delta += wc_nsec; + nsec = do_div(delta, NSEC_PER_SEC); + set_normalized_timespec(&ts, wc_sec + delta, nsec); + /* + * Of all mechanisms of time adjustment I've tested, this one + * was the champion! + */ + return ts.tv_sec + 1; } static int kvm_set_wallclock(unsigned long now) { - return -1; + return 0; } +/* + * This is our read_clock function. The host puts an tsc timestamp each time + * it updates a new time. Without the tsc adjustment, we can have a situation + * in which a vcpu starts to run earlier (smaller system_time), but probes + * time later (compared to another vcpu), leading to backwards time + */ static cycle_t kvm_clock_read(void) { - struct pvclock_vcpu_time_info *src; - cycle_t ret; + u64 last_tsc, now; + int cpu; - src = &get_cpu_var(hv_clock); - ret = pvclock_clocksource_read(src); - put_cpu_var(hv_clock); - return ret; -} + preempt_disable(); + cpu = smp_processor_id(); + + last_tsc = get_clock(cpu, tsc_timestamp); + now = get_clock(cpu, system_time); + + now += kvm_get_delta(last_tsc); + preempt_enable(); + return now; +} static struct clocksource kvm_clock = { .name = "kvm-clock", .read = kvm_clock_read, @@ -88,14 +123,13 @@ static struct clocksource kvm_clock = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static int kvm_register_clock(char *txt) +static int kvm_register_clock(void) { int cpu = smp_processor_id(); int low, high; low = (int)__pa(&per_cpu(hv_clock, cpu)) | 1; high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32); - printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n", - cpu, high, low, txt); + return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high); } @@ -106,20 +140,12 @@ static void kvm_setup_secondary_clock(void) * Now that the first cpu already had this clocksource initialized, * we shouldn't fail. */ - WARN_ON(kvm_register_clock("secondary cpu clock")); + WARN_ON(kvm_register_clock()); /* ok, done with our trickery, call native */ setup_secondary_APIC_clock(); } #endif -#ifdef CONFIG_SMP -void __init kvm_smp_prepare_boot_cpu(void) -{ - WARN_ON(kvm_register_clock("primary cpu clock")); - native_smp_prepare_boot_cpu(); -} -#endif - /* * After the clock is registered, the host will keep writing to the * registered memory location. If the guest happens to shutdown, this memory @@ -148,16 +174,13 @@ void __init kvmclock_init(void) return; if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { - if (kvm_register_clock("boot clock")) + if (kvm_register_clock()) return; pv_time_ops.get_wallclock = kvm_get_wallclock; pv_time_ops.set_wallclock = kvm_set_wallclock; pv_time_ops.sched_clock = kvm_clock_read; #ifdef CONFIG_X86_LOCAL_APIC pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock; -#endif -#ifdef CONFIG_SMP - smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; #endif machine_ops.shutdown = kvm_shutdown; #ifdef CONFIG_KEXEC diff --git a/trunk/arch/x86/kernel/pvclock.c b/trunk/arch/x86/kernel/pvclock.c deleted file mode 100644 index 05fbe9a0325a..000000000000 --- a/trunk/arch/x86/kernel/pvclock.c +++ /dev/null @@ -1,141 +0,0 @@ -/* paravirtual clock -- common code used by kvm/xen - - 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include - -/* - * These are perodically updated - * xen: magic shared_info page - * kvm: gpa registered via msr - * and then copied here. - */ -struct pvclock_shadow_time { - u64 tsc_timestamp; /* TSC at last update of time vals. */ - u64 system_timestamp; /* Time, in nanosecs, since boot. */ - u32 tsc_to_nsec_mul; - int tsc_shift; - u32 version; -}; - -/* - * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, - * yielding a 64-bit result. - */ -static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) -{ - u64 product; -#ifdef __i386__ - u32 tmp1, tmp2; -#endif - - if (shift < 0) - delta >>= -shift; - else - delta <<= shift; - -#ifdef __i386__ - __asm__ ( - "mul %5 ; " - "mov %4,%%eax ; " - "mov %%edx,%4 ; " - "mul %5 ; " - "xor %5,%5 ; " - "add %4,%%eax ; " - "adc %5,%%edx ; " - : "=A" (product), "=r" (tmp1), "=r" (tmp2) - : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); -#elif __x86_64__ - __asm__ ( - "mul %%rdx ; shrd $32,%%rdx,%%rax" - : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); -#else -#error implement me! -#endif - - return product; -} - -static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow) -{ - u64 delta = native_read_tsc() - shadow->tsc_timestamp; - return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift); -} - -/* - * Reads a consistent set of time-base values from hypervisor, - * into a shadow data area. - */ -static unsigned pvclock_get_time_values(struct pvclock_shadow_time *dst, - struct pvclock_vcpu_time_info *src) -{ - do { - dst->version = src->version; - rmb(); /* fetch version before data */ - dst->tsc_timestamp = src->tsc_timestamp; - dst->system_timestamp = src->system_time; - dst->tsc_to_nsec_mul = src->tsc_to_system_mul; - dst->tsc_shift = src->tsc_shift; - rmb(); /* test version after fetching data */ - } while ((src->version & 1) || (dst->version != src->version)); - - return dst->version; -} - -cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) -{ - struct pvclock_shadow_time shadow; - unsigned version; - cycle_t ret, offset; - - do { - version = pvclock_get_time_values(&shadow, src); - barrier(); - offset = pvclock_get_nsec_offset(&shadow); - ret = shadow.system_timestamp + offset; - barrier(); - } while (version != src->version); - - return ret; -} - -void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock, - struct pvclock_vcpu_time_info *vcpu_time, - struct timespec *ts) -{ - u32 version; - u64 delta; - struct timespec now; - - /* get wallclock at system boot */ - do { - version = wall_clock->version; - rmb(); /* fetch version before time */ - now.tv_sec = wall_clock->sec; - now.tv_nsec = wall_clock->nsec; - rmb(); /* fetch time before checking version */ - } while ((wall_clock->version & 1) || (version != wall_clock->version)); - - delta = pvclock_clocksource_read(vcpu_time); /* time since system boot */ - delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec; - - now.tv_nsec = do_div(delta, NSEC_PER_SEC); - now.tv_sec = delta; - - set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); -} diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 3e1cecedde42..56078d61c793 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -996,6 +996,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) #endif cpu_clear(cpu, cpu_callout_map); /* was set by do_boot_cpu() */ cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ + cpu_clear(cpu, cpu_possible_map); cpu_clear(cpu, cpu_present_map); per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID; } diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c index 3829aa7b663f..f2f5d260874e 100644 --- a/trunk/arch/x86/kvm/i8254.c +++ b/trunk/arch/x86/kvm/i8254.c @@ -200,12 +200,9 @@ int __pit_timer_fn(struct kvm_kpit_state *ps) atomic_inc(&pt->pending); smp_mb__after_atomic_inc(); - if (vcpu0) { - set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests); - if (waitqueue_active(&vcpu0->wq)) { - vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE; - wake_up_interruptible(&vcpu0->wq); - } + if (vcpu0 && waitqueue_active(&vcpu0->wq)) { + vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE; + wake_up_interruptible(&vcpu0->wq); } pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period); diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c index ebc03f5ae162..c297c50eba63 100644 --- a/trunk/arch/x86/kvm/lapic.c +++ b/trunk/arch/x86/kvm/lapic.c @@ -940,7 +940,6 @@ static int __apic_timer_fn(struct kvm_lapic *apic) wait_queue_head_t *q = &apic->vcpu->wq; atomic_inc(&apic->timer.pending); - set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests); if (waitqueue_active(q)) { apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; wake_up_interruptible(q); diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 7e7c3969f7a2..ee3f53098f0c 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -640,7 +640,6 @@ static void rmap_write_protect(struct kvm *kvm, u64 gfn) rmap_remove(kvm, spte); --kvm->stat.lpages; set_shadow_pte(spte, shadow_trap_nonpresent_pte); - spte = NULL; write_protected = 1; } spte = rmap_next(kvm, rmapp, spte); @@ -1083,6 +1082,10 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, struct kvm_mmu_page *shadow; spte |= PT_WRITABLE_MASK; + if (user_fault) { + mmu_unshadow(vcpu->kvm, gfn); + goto unshadowed; + } shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn); if (shadow || @@ -1099,6 +1102,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, } } +unshadowed: + if (pte_access & ACC_WRITE_MASK) mark_page_dirty(vcpu->kvm, gfn); @@ -1575,13 +1580,11 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, u64 *spte, const void *new) { - if (sp->role.level != PT_PAGE_TABLE_LEVEL) { - if (!vcpu->arch.update_pte.largepage || - sp->role.glevels == PT32_ROOT_LEVEL) { - ++vcpu->kvm->stat.mmu_pde_zapped; - return; - } - } + if ((sp->role.level != PT_PAGE_TABLE_LEVEL) + && !vcpu->arch.update_pte.largepage) { + ++vcpu->kvm->stat.mmu_pde_zapped; + return; + } ++vcpu->kvm->stat.mmu_pte_updated; if (sp->role.glevels == PT32_ROOT_LEVEL) diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 540e95179074..02efbe75f317 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -566,7 +566,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) load_transition_efer(vmx); } -static void __vmx_load_host_state(struct vcpu_vmx *vmx) +static void vmx_load_host_state(struct vcpu_vmx *vmx) { unsigned long flags; @@ -596,13 +596,6 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx) reload_host_efer(vmx); } -static void vmx_load_host_state(struct vcpu_vmx *vmx) -{ - preempt_disable(); - __vmx_load_host_state(vmx); - preempt_enable(); -} - /* * Switches to specified vcpu, until a matching vcpu_put(), but assumes * vcpu mutex is already taken. @@ -661,7 +654,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) static void vmx_vcpu_put(struct kvm_vcpu *vcpu) { - __vmx_load_host_state(to_vmx(vcpu)); + vmx_load_host_state(to_vmx(vcpu)); } static void vmx_fpu_activate(struct kvm_vcpu *vcpu) @@ -891,8 +884,11 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) switch (msr_index) { #ifdef CONFIG_X86_64 case MSR_EFER: - vmx_load_host_state(vmx); ret = kvm_set_msr_common(vcpu, msr_index, data); + if (vmx->host_state.loaded) { + reload_host_efer(vmx); + load_transition_efer(vmx); + } break; case MSR_FS_BASE: vmcs_writel(GUEST_FS_BASE, data); @@ -914,10 +910,11 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) guest_write_tsc(data); break; default: - vmx_load_host_state(vmx); msr = find_msr_entry(vmx, msr_index); if (msr) { msr->data = data; + if (vmx->host_state.loaded) + load_msrs(vmx->guest_msrs, vmx->save_nmsrs); break; } ret = kvm_set_msr_common(vcpu, msr_index, data); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 63a77caa59f1..00acf1301a15 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -492,8 +492,8 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) { static int version; - struct pvclock_wall_clock wc; - struct timespec now, sys, boot; + struct kvm_wall_clock wc; + struct timespec wc_ts; if (!wall_clock) return; @@ -502,19 +502,10 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); - /* - * The guest calculates current wall clock time by adding - * system time (updated by kvm_write_guest_time below) to the - * wall clock specified here. guest system time equals host - * system time for us, thus we must fill in host boot time here. - */ - now = current_kernel_time(); - ktime_get_ts(&sys); - boot = ns_to_timespec(timespec_to_ns(&now) - timespec_to_ns(&sys)); - - wc.sec = boot.tv_sec; - wc.nsec = boot.tv_nsec; - wc.version = version; + wc_ts = current_kernel_time(); + wc.wc_sec = wc_ts.tv_sec; + wc.wc_nsec = wc_ts.tv_nsec; + wc.wc_version = version; kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc)); @@ -522,45 +513,6 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); } -static uint32_t div_frac(uint32_t dividend, uint32_t divisor) -{ - uint32_t quotient, remainder; - - /* Don't try to replace with do_div(), this one calculates - * "(dividend << 32) / divisor" */ - __asm__ ( "divl %4" - : "=a" (quotient), "=d" (remainder) - : "0" (0), "1" (dividend), "r" (divisor) ); - return quotient; -} - -static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *hv_clock) -{ - uint64_t nsecs = 1000000000LL; - int32_t shift = 0; - uint64_t tps64; - uint32_t tps32; - - tps64 = tsc_khz * 1000LL; - while (tps64 > nsecs*2) { - tps64 >>= 1; - shift--; - } - - tps32 = (uint32_t)tps64; - while (tps32 <= (uint32_t)nsecs) { - tps32 <<= 1; - shift++; - } - - hv_clock->tsc_shift = shift; - hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32); - - pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n", - __FUNCTION__, tsc_khz, hv_clock->tsc_shift, - hv_clock->tsc_to_system_mul); -} - static void kvm_write_guest_time(struct kvm_vcpu *v) { struct timespec ts; @@ -571,11 +523,6 @@ static void kvm_write_guest_time(struct kvm_vcpu *v) if ((!vcpu->time_page)) return; - if (unlikely(vcpu->hv_clock_tsc_khz != tsc_khz)) { - kvm_set_time_scale(tsc_khz, &vcpu->hv_clock); - vcpu->hv_clock_tsc_khz = tsc_khz; - } - /* Keep irq disabled to prevent changes to the clock */ local_irq_save(flags); kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER, @@ -590,14 +537,14 @@ static void kvm_write_guest_time(struct kvm_vcpu *v) /* * The interface expects us to write an even number signaling that the * update is finished. Since the guest won't see the intermediate - * state, we just increase by 2 at the end. + * state, we just write "2" at the end */ - vcpu->hv_clock.version += 2; + vcpu->hv_clock.version = 2; shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0); memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock, - sizeof(vcpu->hv_clock)); + sizeof(vcpu->hv_clock)); kunmap_atomic(shared_kaddr, KM_USER0); @@ -652,6 +599,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) /* ...but clean it before doing the actual write */ vcpu->arch.time_offset = data & ~(PAGE_MASK | 1); + vcpu->arch.hv_clock.tsc_to_system_mul = + clocksource_khz2mult(tsc_khz, 22); + vcpu->arch.hv_clock.tsc_shift = 22; + down_read(¤t->mm->mmap_sem); vcpu->arch.time_page = gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT); @@ -2808,8 +2759,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (vcpu->requests) { if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests)) __kvm_migrate_timers(vcpu); - if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) - kvm_x86_ops->tlb_flush(vcpu); if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests)) { kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS; @@ -2823,7 +2772,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) } } - clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests); kvm_inject_pending_timer_irqs(vcpu); preempt_disable(); @@ -2833,13 +2781,21 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) local_irq_disable(); - if (vcpu->requests || need_resched()) { + if (need_resched()) { local_irq_enable(); preempt_enable(); r = 1; goto out; } + if (vcpu->requests) + if (test_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) { + local_irq_enable(); + preempt_enable(); + r = 1; + goto out; + } + if (signal_pending(current)) { local_irq_enable(); preempt_enable(); @@ -2869,6 +2825,9 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) kvm_guest_enter(); + if (vcpu->requests) + if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) + kvm_x86_ops->tlb_flush(vcpu); KVMTRACE_0D(VMENTRY, vcpu, entryexit); kvm_x86_ops->run(vcpu, kvm_run); diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index f6d20be7a8f4..156e6d7b0e32 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -135,7 +135,7 @@ static __init void *spp_getpage(void) return ptr; } -static __init void +static void set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) { pgd_t *pgd; @@ -214,7 +214,7 @@ void __init cleanup_highmap(void) } /* NOTE: this is meant to be run only at boot */ -void __init __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) +void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) { unsigned long address = __fix_to_virt(idx); @@ -506,7 +506,7 @@ early_param("memtest", parse_memtest); static void __init early_memtest(unsigned long start, unsigned long end) { - unsigned long t_start, t_size; + u64 t_start, t_size; unsigned pattern; if (!memtest_pattern) @@ -525,7 +525,7 @@ static void __init early_memtest(unsigned long start, unsigned long end) if (t_start + t_size > end) t_size = end - t_start; - printk(KERN_CONT "\n %016lx - %016lx pattern %d", + printk(KERN_CONT "\n %016llx - %016llx pattern %d", t_start, t_start + t_size, pattern); memtest(t_start, t_size, pattern); diff --git a/trunk/arch/x86/xen/Kconfig b/trunk/arch/x86/xen/Kconfig index 6c388e593bc8..2e641be2737e 100644 --- a/trunk/arch/x86/xen/Kconfig +++ b/trunk/arch/x86/xen/Kconfig @@ -5,9 +5,8 @@ config XEN bool "Xen guest support" select PARAVIRT - select PARAVIRT_CLOCK depends on X86_32 - depends on X86_CMPXCHG && X86_TSC && X86_PAE && !(X86_VISWS || X86_VOYAGER) + depends on X86_CMPXCHG && X86_TSC && !(X86_VISWS || X86_VOYAGER) help This is the Linux Xen port. Enabling this will allow the kernel to boot in a paravirtualized environment under the diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index f09c1c69c37a..c8a56e457d61 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -785,35 +785,38 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) static __init void xen_pagetable_setup_start(pgd_t *base) { pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base; - int i; /* special set_pte for pagetable initialization */ pv_mmu_ops.set_pte = xen_set_pte_init; init_mm.pgd = base; /* - * copy top-level of Xen-supplied pagetable into place. This - * is a stand-in while we copy the pmd pages. + * copy top-level of Xen-supplied pagetable into place. For + * !PAE we can use this as-is, but for PAE it is a stand-in + * while we copy the pmd pages. */ memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t)); - /* - * For PAE, need to allocate new pmds, rather than - * share Xen's, since Xen doesn't like pmd's being - * shared between address spaces. - */ - for (i = 0; i < PTRS_PER_PGD; i++) { - if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) { - pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); + if (PTRS_PER_PMD > 1) { + int i; + /* + * For PAE, need to allocate new pmds, rather than + * share Xen's, since Xen doesn't like pmd's being + * shared between address spaces. + */ + for (i = 0; i < PTRS_PER_PGD; i++) { + if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) { + pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); - memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]), - PAGE_SIZE); + memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]), + PAGE_SIZE); - make_lowmem_page_readonly(pmd); + make_lowmem_page_readonly(pmd); - set_pgd(&base[i], __pgd(1 + __pa(pmd))); - } else - pgd_clear(&base[i]); + set_pgd(&base[i], __pgd(1 + __pa(pmd))); + } else + pgd_clear(&base[i]); + } } /* make sure zero_page is mapped RO so we can use it in pagetables */ @@ -870,7 +873,17 @@ static __init void xen_pagetable_setup_done(pgd_t *base) /* Actually pin the pagetable down, but we can't set PG_pinned yet because the page structures don't exist yet. */ - pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base))); + { + unsigned level; + +#ifdef CONFIG_X86_PAE + level = MMUEXT_PIN_L3_TABLE; +#else + level = MMUEXT_PIN_L2_TABLE; +#endif + + pin_pagetable_pfn(level, PFN_DOWN(__pa(base))); + } } /* This is called once we have the cpu_possible_map */ @@ -1080,6 +1093,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { .make_pte = xen_make_pte, .make_pgd = xen_make_pgd, +#ifdef CONFIG_X86_PAE .set_pte_atomic = xen_set_pte_atomic, .set_pte_present = xen_set_pte_at, .set_pud = xen_set_pud, @@ -1088,6 +1102,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { .make_pmd = xen_make_pmd, .pmd_val = xen_pmd_val, +#endif /* PAE */ .activate_mm = xen_activate_mm, .dup_mmap = xen_dup_mmap, @@ -1213,11 +1228,6 @@ asmlinkage void __init xen_start_kernel(void) if (xen_feature(XENFEAT_supervisor_mode_kernel)) pv_info.kernel_rpl = 0; - /* Prevent unwanted bits from being set in PTEs. */ - __supported_pte_mask &= ~_PAGE_GLOBAL; - if (!is_initial_xendomain()) - __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); - /* set the limit of our address space */ xen_reserve_top(); diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index df40bf74ea75..3525ef523a74 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -179,56 +179,50 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, preempt_enable(); } -/* Assume pteval_t is equivalent to all the other *val_t types. */ -static pteval_t pte_mfn_to_pfn(pteval_t val) -{ - if (val & _PAGE_PRESENT) { - unsigned long mfn = (val & PTE_MASK) >> PAGE_SHIFT; - pteval_t flags = val & ~PTE_MASK; - val = (mfn_to_pfn(mfn) << PAGE_SHIFT) | flags; - } - - return val; -} - -static pteval_t pte_pfn_to_mfn(pteval_t val) +pteval_t xen_pte_val(pte_t pte) { - if (val & _PAGE_PRESENT) { - unsigned long pfn = (val & PTE_MASK) >> PAGE_SHIFT; - pteval_t flags = val & ~PTE_MASK; - val = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flags; - } + pteval_t ret = pte.pte; - return val; -} + if (ret & _PAGE_PRESENT) + ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; -pteval_t xen_pte_val(pte_t pte) -{ - return pte_mfn_to_pfn(pte.pte); + return ret; } pgdval_t xen_pgd_val(pgd_t pgd) { - return pte_mfn_to_pfn(pgd.pgd); + pgdval_t ret = pgd.pgd; + if (ret & _PAGE_PRESENT) + ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; + return ret; } pte_t xen_make_pte(pteval_t pte) { - pte = pte_pfn_to_mfn(pte); - return native_make_pte(pte); + if (pte & _PAGE_PRESENT) { + pte = phys_to_machine(XPADDR(pte)).maddr; + pte &= ~(_PAGE_PCD | _PAGE_PWT); + } + + return (pte_t){ .pte = pte }; } pgd_t xen_make_pgd(pgdval_t pgd) { - pgd = pte_pfn_to_mfn(pgd); - return native_make_pgd(pgd); + if (pgd & _PAGE_PRESENT) + pgd = phys_to_machine(XPADDR(pgd)).maddr; + + return (pgd_t){ pgd }; } pmdval_t xen_pmd_val(pmd_t pmd) { - return pte_mfn_to_pfn(pmd.pmd); + pmdval_t ret = native_pmd_val(pmd); + if (ret & _PAGE_PRESENT) + ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; + return ret; } - +#ifdef CONFIG_X86_PAE void xen_set_pud(pud_t *ptr, pud_t val) { struct multicall_space mcs; @@ -273,9 +267,17 @@ void xen_pmd_clear(pmd_t *pmdp) pmd_t xen_make_pmd(pmdval_t pmd) { - pmd = pte_pfn_to_mfn(pmd); + if (pmd & _PAGE_PRESENT) + pmd = phys_to_machine(XPADDR(pmd)).maddr; + return native_make_pmd(pmd); } +#else /* !PAE */ +void xen_set_pte(pte_t *ptep, pte_t pte) +{ + *ptep = pte; +} +#endif /* CONFIG_X86_PAE */ /* (Yet another) pagetable walker. This one is intended for pinning a @@ -428,6 +430,8 @@ static int pin_page(struct page *page, enum pt_level level) read-only, and can be pinned. */ void xen_pgd_pin(pgd_t *pgd) { + unsigned level; + xen_mc_batch(); if (pgd_walk(pgd, pin_page, TASK_SIZE)) { @@ -437,7 +441,14 @@ void xen_pgd_pin(pgd_t *pgd) xen_mc_batch(); } - xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd))); +#ifdef CONFIG_X86_PAE + level = MMUEXT_PIN_L3_TABLE; +#else + level = MMUEXT_PIN_L2_TABLE; +#endif + + xen_do_pin(level, PFN_DOWN(__pa(pgd))); + xen_mc_issue(0); } diff --git a/trunk/arch/x86/xen/mmu.h b/trunk/arch/x86/xen/mmu.h index 5fe961caffd4..b5e189b1519d 100644 --- a/trunk/arch/x86/xen/mmu.h +++ b/trunk/arch/x86/xen/mmu.h @@ -37,13 +37,14 @@ void xen_exit_mmap(struct mm_struct *mm); void xen_pgd_pin(pgd_t *pgd); //void xen_pgd_unpin(pgd_t *pgd); -pteval_t xen_pte_val(pte_t); -pmdval_t xen_pmd_val(pmd_t); -pgdval_t xen_pgd_val(pgd_t); +#ifdef CONFIG_X86_PAE +unsigned long long xen_pte_val(pte_t); +unsigned long long xen_pmd_val(pmd_t); +unsigned long long xen_pgd_val(pgd_t); -pte_t xen_make_pte(pteval_t); -pmd_t xen_make_pmd(pmdval_t); -pgd_t xen_make_pgd(pgdval_t); +pte_t xen_make_pte(unsigned long long); +pmd_t xen_make_pmd(unsigned long long); +pgd_t xen_make_pgd(unsigned long long); void xen_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval); @@ -52,4 +53,15 @@ void xen_set_pud(pud_t *ptr, pud_t val); void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); void xen_pmd_clear(pmd_t *pmdp); + +#else +unsigned long xen_pte_val(pte_t); +unsigned long xen_pmd_val(pmd_t); +unsigned long xen_pgd_val(pgd_t); + +pte_t xen_make_pte(unsigned long); +pmd_t xen_make_pmd(unsigned long); +pgd_t xen_make_pgd(unsigned long); +#endif + #endif /* _XEN_MMU_H */ diff --git a/trunk/arch/x86/xen/time.c b/trunk/arch/x86/xen/time.c index 41e217503c96..52b2e3856980 100644 --- a/trunk/arch/x86/xen/time.c +++ b/trunk/arch/x86/xen/time.c @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -32,6 +31,17 @@ static cycle_t xen_clocksource_read(void); +/* These are perodically updated in shared_info, and then copied here. */ +struct shadow_time_info { + u64 tsc_timestamp; /* TSC at last update of time vals. */ + u64 system_timestamp; /* Time, in nanosecs, since boot. */ + u32 tsc_to_nsec_mul; + int tsc_shift; + u32 version; +}; + +static DEFINE_PER_CPU(struct shadow_time_info, shadow_time); + /* runstate info updated by Xen */ static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate); @@ -201,7 +211,7 @@ unsigned long long xen_sched_clock(void) unsigned long xen_cpu_khz(void) { u64 xen_khz = 1000000ULL << 32; - const struct pvclock_vcpu_time_info *info = + const struct vcpu_time_info *info = &HYPERVISOR_shared_info->vcpu_info[0].time; do_div(xen_khz, info->tsc_to_system_mul); @@ -213,26 +223,121 @@ unsigned long xen_cpu_khz(void) return xen_khz; } +/* + * Reads a consistent set of time-base values from Xen, into a shadow data + * area. + */ +static unsigned get_time_values_from_xen(void) +{ + struct vcpu_time_info *src; + struct shadow_time_info *dst; + + /* src is shared memory with the hypervisor, so we need to + make sure we get a consistent snapshot, even in the face of + being preempted. */ + src = &__get_cpu_var(xen_vcpu)->time; + dst = &__get_cpu_var(shadow_time); + + do { + dst->version = src->version; + rmb(); /* fetch version before data */ + dst->tsc_timestamp = src->tsc_timestamp; + dst->system_timestamp = src->system_time; + dst->tsc_to_nsec_mul = src->tsc_to_system_mul; + dst->tsc_shift = src->tsc_shift; + rmb(); /* test version after fetching data */ + } while ((src->version & 1) | (dst->version ^ src->version)); + + return dst->version; +} + +/* + * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, + * yielding a 64-bit result. + */ +static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) +{ + u64 product; +#ifdef __i386__ + u32 tmp1, tmp2; +#endif + + if (shift < 0) + delta >>= -shift; + else + delta <<= shift; + +#ifdef __i386__ + __asm__ ( + "mul %5 ; " + "mov %4,%%eax ; " + "mov %%edx,%4 ; " + "mul %5 ; " + "xor %5,%5 ; " + "add %4,%%eax ; " + "adc %5,%%edx ; " + : "=A" (product), "=r" (tmp1), "=r" (tmp2) + : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); +#elif __x86_64__ + __asm__ ( + "mul %%rdx ; shrd $32,%%rdx,%%rax" + : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); +#else +#error implement me! +#endif + + return product; +} + +static u64 get_nsec_offset(struct shadow_time_info *shadow) +{ + u64 now, delta; + now = native_read_tsc(); + delta = now - shadow->tsc_timestamp; + return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift); +} + static cycle_t xen_clocksource_read(void) { - struct pvclock_vcpu_time_info *src; + struct shadow_time_info *shadow = &get_cpu_var(shadow_time); cycle_t ret; + unsigned version; + + do { + version = get_time_values_from_xen(); + barrier(); + ret = shadow->system_timestamp + get_nsec_offset(shadow); + barrier(); + } while (version != __get_cpu_var(xen_vcpu)->time.version); + + put_cpu_var(shadow_time); - src = &get_cpu_var(xen_vcpu)->time; - ret = pvclock_clocksource_read(src); - put_cpu_var(xen_vcpu); return ret; } static void xen_read_wallclock(struct timespec *ts) { - struct shared_info *s = HYPERVISOR_shared_info; - struct pvclock_wall_clock *wall_clock = &(s->wc); - struct pvclock_vcpu_time_info *vcpu_time; + const struct shared_info *s = HYPERVISOR_shared_info; + u32 version; + u64 delta; + struct timespec now; + + /* get wallclock at system boot */ + do { + version = s->wc_version; + rmb(); /* fetch version before time */ + now.tv_sec = s->wc_sec; + now.tv_nsec = s->wc_nsec; + rmb(); /* fetch time before checking version */ + } while ((s->wc_version & 1) | (version ^ s->wc_version)); - vcpu_time = &get_cpu_var(xen_vcpu)->time; - pvclock_read_wallclock(wall_clock, vcpu_time, ts); - put_cpu_var(xen_vcpu); + delta = xen_clocksource_read(); /* time since system boot */ + delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec; + + now.tv_nsec = do_div(delta, NSEC_PER_SEC); + now.tv_sec = delta; + + set_normalized_timespec(ts, now.tv_sec, now.tv_nsec); } unsigned long xen_get_wallclock(void) @@ -240,6 +345,7 @@ unsigned long xen_get_wallclock(void) struct timespec ts; xen_read_wallclock(&ts); + return ts.tv_sec; } @@ -463,6 +569,8 @@ __init void xen_time_init(void) { int cpu = smp_processor_id(); + get_time_values_from_xen(); + clocksource_register(&xen_clocksource); if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) { diff --git a/trunk/arch/x86/xen/xen-head.S b/trunk/arch/x86/xen/xen-head.S index 6ec3b4f7719b..288d587ce73c 100644 --- a/trunk/arch/x86/xen/xen-head.S +++ b/trunk/arch/x86/xen/xen-head.S @@ -17,7 +17,7 @@ ENTRY(startup_xen) __FINIT -.pushsection .text +.pushsection .bss.page_aligned .align PAGE_SIZE_asm ENTRY(hypercall_page) .skip 0x1000 @@ -30,7 +30,11 @@ ENTRY(hypercall_page) ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long startup_xen) ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long hypercall_page) ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz "!writable_page_tables|pae_pgdir_above_4gb") +#ifdef CONFIG_X86_PAE ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes") +#else + ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "no") +#endif ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") #endif /*CONFIG_XEN */ diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 743f33a01a07..8c3946787dbb 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -831,8 +831,6 @@ static void as_completed_request(struct request_queue *q, struct request *rq) } if (ad->changed_batch && ad->nr_dispatched == 1) { - ad->current_batch_expires = jiffies + - ad->batch_expire[ad->batch_data_dir]; kblockd_schedule_work(&ad->antic_work); ad->changed_batch = 0; diff --git a/trunk/drivers/acpi/bay.c b/trunk/drivers/acpi/bay.c index 61b6c5beb2d3..26038c2a2a71 100644 --- a/trunk/drivers/acpi/bay.c +++ b/trunk/drivers/acpi/bay.c @@ -377,9 +377,6 @@ static int __init bay_init(void) INIT_LIST_HEAD(&drive_bays); - if (acpi_disabled) - return -ENODEV; - /* look for dockable drive bays */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_bay, &bays, NULL); diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index bb7c51f712bd..96c542f7fded 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -917,9 +917,6 @@ static int __init dock_init(void) dock_station = NULL; - if (acpi_disabled) - return 0; - /* look for a dock station */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, find_dock, &num, NULL); diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 9b227d4dc9c9..2808dc60fd67 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -333,9 +333,6 @@ static int __init acpi_rtc_init(void) { struct device *dev = get_rtc_dev(); - if (acpi_disabled) - return 0; - if (dev) { rtc_wake_setup(); rtc_info.wake_on = rtc_wake_on; diff --git a/trunk/drivers/char/drm/i915_drv.c b/trunk/drivers/char/drm/i915_drv.c index 93aed1c38bd2..e8f3d682e3b1 100644 --- a/trunk/drivers/char/drm/i915_drv.c +++ b/trunk/drivers/char/drm/i915_drv.c @@ -389,7 +389,6 @@ static int i915_resume(struct drm_device *dev) pci_restore_state(dev->pdev); if (pci_enable_device(dev->pdev)) return -1; - pci_set_master(dev->pdev); pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); diff --git a/trunk/drivers/char/drm/i915_irq.c b/trunk/drivers/char/drm/i915_irq.c index df036118b8b1..f7f16e7a8bf3 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -62,11 +62,11 @@ static void i915_vblank_tasklet(struct drm_device *dev) u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); RING_LOCALS; - if (IS_I965G(dev) && sarea_priv->front_tiled) { + if (sarea_priv->front_tiled) { cmd |= XY_SRC_COPY_BLT_DST_TILED; dst_pitch >>= 2; } - if (IS_I965G(dev) && sarea_priv->back_tiled) { + if (sarea_priv->back_tiled) { cmd |= XY_SRC_COPY_BLT_SRC_TILED; src_pitch >>= 2; } diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 750131010af0..e94bee032314 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -3322,7 +3322,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration) msleep_interruptible(duration); tty->ops->break_ctl(tty, 0); tty_write_unlock(tty); - if (signal_pending(current)) + if (!signal_pending(current)) return -EINTR; return 0; } diff --git a/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c index 8f81139d6194..b1a757a5ee27 100644 --- a/trunk/drivers/char/tty_ioctl.c +++ b/trunk/drivers/char/tty_ioctl.c @@ -981,9 +981,16 @@ EXPORT_SYMBOL_GPL(tty_perform_flush); int n_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { + struct tty_struct *real_tty; unsigned long flags; int retval; + if (tty->driver->type == TTY_DRIVER_TYPE_PTY && + tty->driver->subtype == PTY_TYPE_MASTER) + real_tty = tty->link; + else + real_tty = tty; + switch (cmd) { case TCXONC: retval = tty_check_change(tty); diff --git a/trunk/drivers/connector/connector.c b/trunk/drivers/connector/connector.c index bf4830082a13..85e2ba7fcfba 100644 --- a/trunk/drivers/connector/connector.c +++ b/trunk/drivers/connector/connector.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include @@ -405,40 +403,6 @@ static void cn_callback(void *data) mutex_unlock(¬ify_lock); } -static int cn_proc_show(struct seq_file *m, void *v) -{ - struct cn_queue_dev *dev = cdev.cbdev; - struct cn_callback_entry *cbq; - - seq_printf(m, "Name ID\n"); - - spin_lock_bh(&dev->queue_lock); - - list_for_each_entry(cbq, &dev->queue_list, callback_entry) { - seq_printf(m, "%-15s %u:%u\n", - cbq->id.name, - cbq->id.id.idx, - cbq->id.id.val); - } - - spin_unlock_bh(&dev->queue_lock); - - return 0; -} - -static int cn_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, cn_proc_show, NULL); -} - -static const struct file_operations cn_file_ops = { - .owner = THIS_MODULE, - .open = cn_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release -}; - static int __devinit cn_init(void) { struct cn_dev *dev = &cdev; @@ -470,8 +434,6 @@ static int __devinit cn_init(void) return -EINVAL; } - proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops); - return 0; } @@ -481,8 +443,6 @@ static void __devexit cn_fini(void) cn_already_initialized = 0; - proc_net_remove(&init_net, "connector"); - cn_del_callback(&dev->id); cn_queue_free_dev(dev->cbdev); netlink_kernel_release(dev->nls); diff --git a/trunk/drivers/firewire/fw-sbp2.c b/trunk/drivers/firewire/fw-sbp2.c index 227d2e036cd8..b2458bb8e9ca 100644 --- a/trunk/drivers/firewire/fw-sbp2.c +++ b/trunk/drivers/firewire/fw-sbp2.c @@ -1051,8 +1051,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory, break; case SBP2_CSR_LOGICAL_UNIT_DIRECTORY: - /* Adjust for the increment in the iterator */ - if (sbp2_scan_logical_unit_dir(tgt, ci.p - 1 + value) < 0) + if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0) return -ENOMEM; break; } diff --git a/trunk/drivers/hwmon/abituguru3.c b/trunk/drivers/hwmon/abituguru3.c index f00f497b9ca9..ed33fddc4dee 100644 --- a/trunk/drivers/hwmon/abituguru3.c +++ b/trunk/drivers/hwmon/abituguru3.c @@ -30,7 +30,6 @@ #include #include #include -#include #include /* uGuru3 bank addresses */ @@ -324,7 +323,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX1 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0013, "Abit AW8D", { + { 0x0013, "unknown", { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 10, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -350,7 +349,6 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { { "AUX2 Fan", 36, 2, 60, 1, 0 }, { "AUX3 Fan", 37, 2, 60, 1, 0 }, { "AUX4 Fan", 38, 2, 60, 1, 0 }, - { "AUX5 Fan", 39, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, { 0x0014, "Abit AB9 Pro", { @@ -1113,12 +1111,11 @@ static int __init abituguru3_detect(void) { /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or 0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05 - or 0x55 at CMD instead, why is unknown. */ + at CMD instead, why is unknown. So we test for 0x05 too. */ u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA); u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD); if (((data_val == 0x00) || (data_val == 0x08)) && - ((cmd_val == 0xAC) || (cmd_val == 0x05) || - (cmd_val == 0x55))) + ((cmd_val == 0xAC) || (cmd_val == 0x05))) return ABIT_UGURU3_BASE; ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " @@ -1141,15 +1138,6 @@ static int __init abituguru3_init(void) int address, err; struct resource res = { .flags = IORESOURCE_IO }; -#ifdef CONFIG_DMI - const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); - - /* safety check, refuse to load on non Abit motherboards */ - if (!force && (!board_vendor || - strcmp(board_vendor, "http://www.abit.com.tw/"))) - return -ENODEV; -#endif - address = abituguru3_detect(); if (address < 0) return address; diff --git a/trunk/drivers/hwmon/adt7473.c b/trunk/drivers/hwmon/adt7473.c index 93dbf5e7ff8a..c1009d6f9796 100644 --- a/trunk/drivers/hwmon/adt7473.c +++ b/trunk/drivers/hwmon/adt7473.c @@ -309,9 +309,6 @@ static struct adt7473_data *adt7473_update_device(struct device *dev) ADT7473_REG_PWM_BHVR(i)); } - i = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4); - data->max_duty_at_overheat = !!(i & ADT7473_CFG4_MAX_DUTY_AT_OVT); - data->limits_last_updated = local_jiffies; data->limits_valid = 1; diff --git a/trunk/drivers/hwmon/lm75.c b/trunk/drivers/hwmon/lm75.c index de698dc73020..fa7696905154 100644 --- a/trunk/drivers/hwmon/lm75.c +++ b/trunk/drivers/hwmon/lm75.c @@ -251,13 +251,10 @@ static int lm75_detach_client(struct i2c_client *client) the SMBus standard. */ static int lm75_read_value(struct i2c_client *client, u8 reg) { - int value; - if (reg == LM75_REG_CONF) return i2c_smbus_read_byte_data(client, reg); - - value = i2c_smbus_read_word_data(client, reg); - return (value < 0) ? value : swab16(value); + else + return swab16(i2c_smbus_read_word_data(client, reg)); } static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) @@ -290,16 +287,9 @@ static struct lm75_data *lm75_update_device(struct device *dev) int i; dev_dbg(&client->dev, "Starting lm75 update\n"); - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { - int status; - - status = lm75_read_value(client, LM75_REG_TEMP[i]); - if (status < 0) - dev_dbg(&client->dev, "reg %d, err %d\n", - LM75_REG_TEMP[i], status); - else - data->temp[i] = status; - } + for (i = 0; i < ARRAY_SIZE(data->temp); i++) + data->temp[i] = lm75_read_value(client, + LM75_REG_TEMP[i]); data->last_updated = jiffies; data->valid = 1; } diff --git a/trunk/drivers/hwmon/lm85.c b/trunk/drivers/hwmon/lm85.c index ee5eca1c1921..182fe6a5605f 100644 --- a/trunk/drivers/hwmon/lm85.c +++ b/trunk/drivers/hwmon/lm85.c @@ -192,20 +192,23 @@ static int RANGE_TO_REG( int range ) { int i; - if (range >= lm85_range_map[15]) + if ( range < lm85_range_map[0] ) { + return 0 ; + } else if ( range > lm85_range_map[15] ) { return 15 ; - - /* Find the closest match */ - for (i = 14; i >= 0; --i) { - if (range >= lm85_range_map[i]) { - if ((lm85_range_map[i + 1] - range) < - (range - lm85_range_map[i])) - return i + 1; - return i; + } else { /* find closest match */ + for ( i = 14 ; i >= 0 ; --i ) { + if ( range > lm85_range_map[i] ) { /* range bracketed */ + if ((lm85_range_map[i+1] - range) < + (range - lm85_range_map[i])) { + i++; + break; + } + break; + } } } - - return 0; + return( i & 0x0f ); } #define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f]) diff --git a/trunk/drivers/i2c/busses/i2c-s3c2410.c b/trunk/drivers/i2c/busses/i2c-s3c2410.c index 9e8c875437be..1305ef190fc1 100644 --- a/trunk/drivers/i2c/busses/i2c-s3c2410.c +++ b/trunk/drivers/i2c/busses/i2c-s3c2410.c @@ -290,12 +290,12 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) * bus, or started a new i2c message */ - if (iicstat & S3C2410_IICSTAT_LASTBIT && + if (iicstat & S3C2410_IICSTAT_LASTBIT && !(i2c->msg->flags & I2C_M_IGNORE_NAK)) { /* ack was not received... */ dev_dbg(i2c->dev, "ack was not received\n"); - s3c24xx_i2c_stop(i2c, -ENXIO); + s3c24xx_i2c_stop(i2c, -EREMOTEIO); goto out_ack; } @@ -305,7 +305,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) i2c->state = STATE_WRITE; /* terminate the transfer if there is nothing to do - * as this is used by the i2c probe to find devices. */ + * (used by the i2c probe to find devices */ if (is_lastmsg(i2c) && i2c->msg->len == 0) { s3c24xx_i2c_stop(i2c, 0); @@ -323,17 +323,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) * end of the message, and if so, work out what to do */ - if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) { - if (iicstat & S3C2410_IICSTAT_LASTBIT) { - dev_dbg(i2c->dev, "WRITE: No Ack\n"); - - s3c24xx_i2c_stop(i2c, -ECONNREFUSED); - goto out_ack; - } - } - retry_write: - if (!is_msgend(i2c)) { byte = i2c->msg->buf[i2c->msg_ptr++]; writeb(byte, i2c->regs + S3C2410_IICDS); @@ -387,6 +377,17 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) * going to do any more read/write */ + if (!(i2c->msg->flags & I2C_M_IGNORE_NAK) && + !(is_msglast(i2c) && is_lastmsg(i2c))) { + + if (iicstat & S3C2410_IICSTAT_LASTBIT) { + dev_dbg(i2c->dev, "READ: No Ack\n"); + + s3c24xx_i2c_stop(i2c, -ECONNREFUSED); + goto out_ack; + } + } + byte = readb(i2c->regs + S3C2410_IICDS); i2c->msg->buf[i2c->msg_ptr++] = byte; @@ -948,4 +949,3 @@ MODULE_DESCRIPTION("S3C24XX I2C Bus driver"); MODULE_AUTHOR("Ben Dooks, "); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:s3c2410-i2c"); -MODULE_ALIAS("platform:s3c2440-i2c"); diff --git a/trunk/drivers/i2c/chips/isp1301_omap.c b/trunk/drivers/i2c/chips/isp1301_omap.c index 03a33f1b9cd3..b1b45dddb17e 100644 --- a/trunk/drivers/i2c/chips/isp1301_omap.c +++ b/trunk/drivers/i2c/chips/isp1301_omap.c @@ -72,7 +72,7 @@ struct isp1301 { }; -/* bits in OTG_CTRL */ +/* bits in OTG_CTRL_REG */ #define OTG_XCEIV_OUTPUTS \ (OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID) @@ -186,8 +186,8 @@ isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits) /* operational registers */ #define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */ -# define MC1_SPEED (1 << 0) -# define MC1_SUSPEND (1 << 1) +# define MC1_SPEED_REG (1 << 0) +# define MC1_SUSPEND_REG (1 << 1) # define MC1_DAT_SE0 (1 << 2) # define MC1_TRANSPARENT (1 << 3) # define MC1_BDIS_ACON_EN (1 << 4) @@ -274,7 +274,7 @@ static void power_down(struct isp1301 *isp) isp->otg.state = OTG_STATE_UNDEFINED; // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); + isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN); isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0); @@ -283,7 +283,7 @@ static void power_down(struct isp1301 *isp) static void power_up(struct isp1301 *isp) { // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN); - isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND); + isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG); /* do this only when cpu is driving transceiver, * so host won't see a low speed device... @@ -360,8 +360,6 @@ isp1301_defer_work(struct isp1301 *isp, int work) /* called from irq handlers */ static void a_idle(struct isp1301 *isp, const char *tag) { - u32 l; - if (isp->otg.state == OTG_STATE_A_IDLE) return; @@ -375,17 +373,13 @@ static void a_idle(struct isp1301 *isp, const char *tag) gadget_suspend(isp); } isp->otg.state = OTG_STATE_A_IDLE; - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - isp->last_otg_ctrl = l; + isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; pr_debug(" --> %s/%s\n", state_name(isp), tag); } /* called from irq handlers */ static void b_idle(struct isp1301 *isp, const char *tag) { - u32 l; - if (isp->otg.state == OTG_STATE_B_IDLE) return; @@ -399,9 +393,7 @@ static void b_idle(struct isp1301 *isp, const char *tag) gadget_suspend(isp); } isp->otg.state = OTG_STATE_B_IDLE; - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - isp->last_otg_ctrl = l; + isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; pr_debug(" --> %s/%s\n", state_name(isp), tag); } @@ -414,7 +406,7 @@ dump_regs(struct isp1301 *isp, const char *label) u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE); pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n", - omap_readl(OTG_CTRL), label, state_name(isp), + OTG_CTRL_REG, label, state_name(isp), ctrl, status, src); /* mode control and irq enables don't change much */ #endif @@ -437,7 +429,7 @@ dump_regs(struct isp1301 *isp, const char *label) static void check_state(struct isp1301 *isp, const char *tag) { enum usb_otg_state state = OTG_STATE_UNDEFINED; - u8 fsm = omap_readw(OTG_TEST) & 0x0ff; + u8 fsm = OTG_TEST_REG & 0x0ff; unsigned extra = 0; switch (fsm) { @@ -502,8 +494,7 @@ static void check_state(struct isp1301 *isp, const char *tag) if (isp->otg.state == state && !extra) return; pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag, - state_string(state), fsm, state_name(isp), - omap_readl(OTG_CTRL)); + state_string(state), fsm, state_name(isp), OTG_CTRL_REG); } #else @@ -517,11 +508,10 @@ static void update_otg1(struct isp1301 *isp, u8 int_src) { u32 otg_ctrl; - otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - otg_ctrl &= ~OTG_XCEIV_INPUTS; - otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); - - + otg_ctrl = OTG_CTRL_REG + & OTG_CTRL_MASK + & ~OTG_XCEIV_INPUTS + & ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD); if (int_src & INTR_SESS_VLD) otg_ctrl |= OTG_ASESSVLD; else if (isp->otg.state == OTG_STATE_A_WAIT_VFALL) { @@ -544,7 +534,7 @@ static void update_otg1(struct isp1301 *isp, u8 int_src) return; } } - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; } /* outputs from ISP1301_OTG_STATUS */ @@ -552,14 +542,15 @@ static void update_otg2(struct isp1301 *isp, u8 otg_status) { u32 otg_ctrl; - otg_ctrl = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - otg_ctrl &= ~OTG_XCEIV_INPUTS; - otg_ctrl &= ~(OTG_BSESSVLD | OTG_BSESSEND); + otg_ctrl = OTG_CTRL_REG + & OTG_CTRL_MASK + & ~OTG_XCEIV_INPUTS + & ~(OTG_BSESSVLD|OTG_BSESSEND); if (otg_status & OTG_B_SESS_VLD) otg_ctrl |= OTG_BSESSVLD; else if (otg_status & OTG_B_SESS_END) otg_ctrl |= OTG_BSESSEND; - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; } /* inputs going to ISP1301 */ @@ -568,7 +559,7 @@ static void otg_update_isp(struct isp1301 *isp) u32 otg_ctrl, otg_change; u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP; - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; otg_change = otg_ctrl ^ isp->last_otg_ctrl; isp->last_otg_ctrl = otg_ctrl; otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS; @@ -648,8 +639,6 @@ static void otg_update_isp(struct isp1301 *isp) /* HNP switch to host or peripheral; and SRP */ if (otg_change & OTG_PULLUP) { - u32 l; - switch (isp->otg.state) { case OTG_STATE_B_IDLE: if (clr & OTG1_DP_PULLUP) @@ -666,9 +655,7 @@ static void otg_update_isp(struct isp1301 *isp) default: break; } - l = omap_readl(OTG_CTRL); - l |= OTG_PULLUP; - omap_writel(l, OTG_CTRL); + OTG_CTRL_REG |= OTG_PULLUP; } check_state(isp, __func__); @@ -677,20 +664,20 @@ static void otg_update_isp(struct isp1301 *isp) static irqreturn_t omap_otg_irq(int irq, void *_isp) { - u16 otg_irq = omap_readw(OTG_IRQ_SRC); + u16 otg_irq = OTG_IRQ_SRC_REG; u32 otg_ctrl; int ret = IRQ_NONE; struct isp1301 *isp = _isp; /* update ISP1301 transciever from OTG controller */ if (otg_irq & OPRT_CHG) { - omap_writew(OPRT_CHG, OTG_IRQ_SRC); + OTG_IRQ_SRC_REG = OPRT_CHG; isp1301_defer_work(isp, WORK_UPDATE_ISP); ret = IRQ_HANDLED; /* SRP to become b_peripheral failed */ } else if (otg_irq & B_SRP_TMROUT) { - pr_debug("otg: B_SRP_TIMEOUT, %06x\n", omap_readl(OTG_CTRL)); + pr_debug("otg: B_SRP_TIMEOUT, %06x\n", OTG_CTRL_REG); notresponding(isp); /* gadget drivers that care should monitor all kinds of @@ -700,31 +687,31 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) if (isp->otg.state == OTG_STATE_B_SRP_INIT) b_idle(isp, "srp_timeout"); - omap_writew(B_SRP_TMROUT, OTG_IRQ_SRC); + OTG_IRQ_SRC_REG = B_SRP_TMROUT; ret = IRQ_HANDLED; /* HNP to become b_host failed */ } else if (otg_irq & B_HNP_FAIL) { pr_debug("otg: %s B_HNP_FAIL, %06x\n", - state_name(isp), omap_readl(OTG_CTRL)); + state_name(isp), OTG_CTRL_REG); notresponding(isp); - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; otg_ctrl |= OTG_BUSDROP; otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; /* subset of b_peripheral()... */ isp->otg.state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); - omap_writew(B_HNP_FAIL, OTG_IRQ_SRC); + OTG_IRQ_SRC_REG = B_HNP_FAIL; ret = IRQ_HANDLED; /* detect SRP from B-device ... */ } else if (otg_irq & A_SRP_DETECT) { pr_debug("otg: %s SRP_DETECT, %06x\n", - state_name(isp), omap_readl(OTG_CTRL)); + state_name(isp), OTG_CTRL_REG); isp1301_defer_work(isp, WORK_UPDATE_OTG); switch (isp->otg.state) { @@ -732,49 +719,49 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) if (!isp->otg.host) break; isp1301_defer_work(isp, WORK_HOST_RESUME); - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & ~OTG_XCEIV_INPUTS & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; break; default: break; } - omap_writew(A_SRP_DETECT, OTG_IRQ_SRC); + OTG_IRQ_SRC_REG = A_SRP_DETECT; ret = IRQ_HANDLED; /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise) * we don't track them separately */ } else if (otg_irq & A_REQ_TMROUT) { - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; pr_info("otg: BCON_TMOUT from %s, %06x\n", state_name(isp), otg_ctrl); notresponding(isp); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; isp->otg.state = OTG_STATE_A_WAIT_VFALL; - omap_writew(A_REQ_TMROUT, OTG_IRQ_SRC); + OTG_IRQ_SRC_REG = A_REQ_TMROUT; ret = IRQ_HANDLED; /* A-supplied voltage fell too low; overcurrent */ } else if (otg_irq & A_VBUS_ERR) { - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n", state_name(isp), otg_irq, otg_ctrl); otg_ctrl |= OTG_BUSDROP; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; isp->otg.state = OTG_STATE_A_VBUS_ERR; - omap_writew(A_VBUS_ERR, OTG_IRQ_SRC); + OTG_IRQ_SRC_REG = A_VBUS_ERR; ret = IRQ_HANDLED; /* switch driver; the transciever code activates it, @@ -783,7 +770,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) } else if (otg_irq & DRIVER_SWITCH) { int kick = 0; - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n", state_name(isp), (otg_ctrl & OTG_DRIVER_SEL) @@ -806,7 +793,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) } else { if (!(otg_ctrl & OTG_ID)) { otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS; - omap_writel(otg_ctrl | OTG_A_BUSREQ, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl | OTG_A_BUSREQ; } if (isp->otg.host) { @@ -831,7 +818,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp) } } - omap_writew(DRIVER_SWITCH, OTG_IRQ_SRC); + OTG_IRQ_SRC_REG = DRIVER_SWITCH; ret = IRQ_HANDLED; if (kick) @@ -847,15 +834,12 @@ static struct platform_device *otg_dev; static int otg_init(struct isp1301 *isp) { - u32 l; - if (!otg_dev) return -ENODEV; dump_regs(isp, __func__); /* some of these values are board-specific... */ - l = omap_readl(OTG_SYSCON_2); - l |= OTG_EN + OTG_SYSCON_2_REG |= OTG_EN /* for B-device: */ | SRP_GPDATA /* 9msec Bdev D+ pulse */ | SRP_GPDVBUS /* discharge after VBUS pulse */ @@ -865,22 +849,18 @@ static int otg_init(struct isp1301 *isp) | SRP_DPW /* detect 167+ns SRP pulses */ | SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */ ; - omap_writel(l, OTG_SYSCON_2); update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE)); update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS)); check_state(isp, __func__); pr_debug("otg: %s, %s %06x\n", - state_name(isp), __func__, omap_readl(OTG_CTRL)); + state_name(isp), __func__, OTG_CTRL_REG); - omap_writew(DRIVER_SWITCH | OPRT_CHG + OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG | B_SRP_TMROUT | B_HNP_FAIL - | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT, OTG_IRQ_EN); - - l = omap_readl(OTG_SYSCON_2); - l |= OTG_EN; - omap_writel(l, OTG_SYSCON_2); + | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT; + OTG_SYSCON_2_REG |= OTG_EN; return 0; } @@ -947,11 +927,7 @@ static void otg_unbind(struct isp1301 *isp) static void b_peripheral(struct isp1301 *isp) { - u32 l; - - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); - + OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; usb_gadget_vbus_connect(isp->otg.gadget); #ifdef CONFIG_USB_OTG @@ -1023,8 +999,6 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) isp_bstat = 0; } } else { - u32 l; - /* if user unplugged mini-A end of cable, * don't bypass A_WAIT_VFALL. */ @@ -1045,9 +1019,8 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_BDIS_ACON_EN); isp->otg.state = OTG_STATE_B_IDLE; - l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - l &= ~OTG_CTRL_BITS; - omap_writel(l, OTG_CTRL); + OTG_CTRL_REG &= OTG_CTRL_REG & OTG_CTRL_MASK + & ~OTG_CTRL_BITS; break; case OTG_STATE_B_IDLE: break; @@ -1073,8 +1046,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat) /* FALLTHROUGH */ case OTG_STATE_B_SRP_INIT: b_idle(isp, __func__); - l = omap_readl(OTG_CTRL) & OTG_XCEIV_OUTPUTS; - omap_writel(l, OTG_CTRL); + OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; /* FALLTHROUGH */ case OTG_STATE_B_IDLE: if (isp->otg.gadget && (isp_bstat & OTG_B_SESS_VLD)) { @@ -1158,11 +1130,11 @@ isp1301_work(struct work_struct *work) case OTG_STATE_A_WAIT_VRISE: isp->otg.state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; break; case OTG_STATE_B_WAIT_ACON: isp->otg.state = OTG_STATE_B_HOST; @@ -1302,7 +1274,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host) return -ENODEV; if (!host) { - omap_writew(0, OTG_IRQ_EN); + OTG_IRQ_EN_REG = 0; power_down(isp); isp->otg.host = 0; return 0; @@ -1353,13 +1325,12 @@ static int isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) { struct isp1301 *isp = container_of(otg, struct isp1301, otg); - u32 l; if (!otg || isp != the_transceiver) return -ENODEV; if (!gadget) { - omap_writew(0, OTG_IRQ_EN); + OTG_IRQ_EN_REG = 0; if (!isp->otg.default_a) enable_vbus_draw(isp, 0); usb_gadget_vbus_disconnect(isp->otg.gadget); @@ -1380,11 +1351,9 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) isp->otg.gadget = gadget; // FIXME update its refcount - l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; - l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); - l |= OTG_ID; - omap_writel(l, OTG_CTRL); - + OTG_CTRL_REG = (OTG_CTRL_REG & OTG_CTRL_MASK + & ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS)) + | OTG_ID; power_up(isp); isp->otg.state = OTG_STATE_B_IDLE; @@ -1436,17 +1405,16 @@ isp1301_start_srp(struct otg_transceiver *dev) || isp->otg.state != OTG_STATE_B_IDLE) return -ENODEV; - otg_ctrl = omap_readl(OTG_CTRL); + otg_ctrl = OTG_CTRL_REG; if (!(otg_ctrl & OTG_BSESSEND)) return -EINVAL; otg_ctrl |= OTG_B_BUSREQ; otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK; - omap_writel(otg_ctrl, OTG_CTRL); + OTG_CTRL_REG = otg_ctrl; isp->otg.state = OTG_STATE_B_SRP_INIT; - pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), - omap_readl(OTG_CTRL)); + pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG); #ifdef CONFIG_USB_OTG check_state(isp, __func__); #endif @@ -1458,7 +1426,6 @@ isp1301_start_hnp(struct otg_transceiver *dev) { #ifdef CONFIG_USB_OTG struct isp1301 *isp = container_of(dev, struct isp1301, otg); - u32 l; if (!dev || isp != the_transceiver) return -ENODEV; @@ -1485,9 +1452,7 @@ isp1301_start_hnp(struct otg_transceiver *dev) #endif /* caller must suspend then clear A_BUSREQ */ usb_gadget_vbus_connect(isp->otg.gadget); - l = omap_readl(OTG_CTRL); - l |= OTG_A_SETB_HNPEN; - omap_writel(l, OTG_CTRL); + OTG_CTRL_REG |= OTG_A_SETB_HNPEN; break; case OTG_STATE_A_PERIPHERAL: @@ -1497,7 +1462,7 @@ isp1301_start_hnp(struct otg_transceiver *dev) return -EILSEQ; } pr_debug("otg: HNP %s, %06x ...\n", - state_name(isp), omap_readl(OTG_CTRL)); + state_name(isp), OTG_CTRL_REG); check_state(isp, __func__); return 0; #else diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index 1607536ff5fb..8e07de23d220 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -823,13 +823,6 @@ config BLK_DEV_IDE_RAPIDE Say Y here if you want to support the Yellowstone RapIDE controller manufactured for use with Acorn computers. -config BLK_DEV_IDE_BAST - tristate "Simtec BAST / Thorcom VR1000 IDE support" - depends on ARM && (ARCH_BAST || MACH_VR1000) - help - Say Y here if you want to support the onboard IDE channels on the - Simtec BAST or the Thorcom VR1000 - config IDE_H8300 tristate "H8300 IDE support" depends on H8300 diff --git a/trunk/drivers/ide/arm/Makefile b/trunk/drivers/ide/arm/Makefile index 936e7b0237f5..5bc26053afa6 100644 --- a/trunk/drivers/ide/arm/Makefile +++ b/trunk/drivers/ide/arm/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o -obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o ifeq ($(CONFIG_IDE_ARM), m) diff --git a/trunk/drivers/ide/arm/bast-ide.c b/trunk/drivers/ide/arm/bast-ide.c deleted file mode 100644 index 8e8c28104b45..000000000000 --- a/trunk/drivers/ide/arm/bast-ide.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2003-2004 Simtec Electronics - * Ben Dooks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * -*/ - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#define DRV_NAME "bast-ide" - -static int __init bastide_register(unsigned int base, unsigned int aux, int irq) -{ - ide_hwif_t *hwif; - hw_regs_t hw; - int i; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; - - memset(&hw, 0, sizeof(hw)); - - base += BAST_IDE_CS; - aux += BAST_IDE_CS; - - for (i = 0; i <= 7; i++) { - hw.io_ports_array[i] = (unsigned long)base; - base += 0x20; - } - - hw.io_ports.ctl_addr = aux + (6 * 0x20); - hw.irq = irq; - hw.chipset = ide_generic; - - hwif = ide_find_port(); - if (hwif == NULL) - goto out; - - i = hwif->index; - - ide_init_port_data(hwif, i); - ide_init_port_hw(hwif, &hw); - hwif->port_ops = NULL; - - idx[0] = i; - - ide_device_add(idx, NULL); -out: - return 0; -} - -static int __init bastide_init(void) -{ - unsigned long base = BAST_VA_IDEPRI + BAST_IDE_CS; - - /* we can treat the VR1000 and the BAST the same */ - - if (!(machine_is_bast() || machine_is_vr1000())) - return 0; - - printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n"); - - if (!request_mem_region(base, 0x400000, DRV_NAME)) { - printk(KERN_ERR "%s: resources busy\n", DRV_NAME); - return -EBUSY; - } - - bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0); - bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1); - - return 0; -} - -module_init(bastide_init); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Simtec BAST / Thorcom VR1000 IDE driver"); diff --git a/trunk/drivers/ide/ide-proc.c b/trunk/drivers/ide/ide-proc.c index 8af88bf0969b..55ec7f798772 100644 --- a/trunk/drivers/ide/ide-proc.c +++ b/trunk/drivers/ide/ide-proc.c @@ -76,7 +76,7 @@ static int proc_ide_read_mate ide_hwif_t *hwif = (ide_hwif_t *) data; int len; - if (hwif && hwif->mate) + if (hwif && hwif->mate && hwif->mate->present) len = sprintf(page, "%s\n", hwif->mate->name); else len = sprintf(page, "(none)\n"); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c index d5862e5d99a0..b224079d4e1f 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -109,11 +109,7 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m { struct page *page; - /* - * Use __GFP_ZERO because buggy firmware assumes ICM pages are - * cleared, and subtle failures are seen if they aren't. - */ - page = alloc_pages(gfp_mask | __GFP_ZERO, order); + page = alloc_pages(gfp_mask, order); if (!page) return -ENOMEM; diff --git a/trunk/drivers/input/ff-core.c b/trunk/drivers/input/ff-core.c index 72c63e5dd630..eebc72465fc9 100644 --- a/trunk/drivers/input/ff-core.c +++ b/trunk/drivers/input/ff-core.c @@ -28,7 +28,6 @@ #include #include #include -#include /* * Check that the effect_id is a valid effect and whether the user @@ -167,10 +166,8 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, if (ret) goto out; - spin_lock_irq(&dev->event_lock); ff->effects[id] = *effect; ff->effect_owners[id] = file; - spin_unlock_irq(&dev->event_lock); out: mutex_unlock(&ff->mutex); @@ -192,22 +189,16 @@ static int erase_effect(struct input_dev *dev, int effect_id, if (error) return error; - spin_lock_irq(&dev->event_lock); ff->playback(dev, effect_id, 0); - ff->effect_owners[effect_id] = NULL; - spin_unlock_irq(&dev->event_lock); if (ff->erase) { error = ff->erase(dev, effect_id); - if (error) { - spin_lock_irq(&dev->event_lock); - ff->effect_owners[effect_id] = file; - spin_unlock_irq(&dev->event_lock); - + if (error) return error; - } } + ff->effect_owners[effect_id] = NULL; + return 0; } @@ -272,6 +263,8 @@ int input_ff_event(struct input_dev *dev, unsigned int type, if (type != EV_FF) return 0; + mutex_lock(&ff->mutex); + switch (code) { case FF_GAIN: if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff) @@ -293,6 +286,7 @@ int input_ff_event(struct input_dev *dev, unsigned int type, break; } + mutex_unlock(&ff->mutex); return 0; } EXPORT_SYMBOL_GPL(input_ff_event); diff --git a/trunk/drivers/lguest/x86/core.c b/trunk/drivers/lguest/x86/core.c index 2e554a4ab337..5126d5d9ea0e 100644 --- a/trunk/drivers/lguest/x86/core.c +++ b/trunk/drivers/lguest/x86/core.c @@ -176,7 +176,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) * we set it now, so we can trap and pass that trap to the Guest if it * uses the FPU. */ if (cpu->ts) - unlazy_fpu(current); + lguest_set_ts(); /* SYSENTER is an optimized way of doing system calls. We can't allow * it because it always jumps to privilege level 0. A normal Guest @@ -196,10 +196,6 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) * trap made the switcher code come back, and an error code which some * traps set. */ - /* Restore SYSENTER if it's supposed to be on. */ - if (boot_cpu_has(X86_FEATURE_SEP)) - wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); - /* If the Guest page faulted, then the cr2 register will tell us the * bad virtual address. We have to grab this now, because once we * re-enable interrupts an interrupt could fault and thus overwrite @@ -207,12 +203,13 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) if (cpu->regs->trapnum == 14) cpu->arch.last_pagefault = read_cr2(); /* Similarly, if we took a trap because the Guest used the FPU, - * we have to restore the FPU it expects to see. - * math_state_restore() may sleep and we may even move off to - * a different CPU. So all the critical stuff should be done - * before this. */ + * we have to restore the FPU it expects to see. */ else if (cpu->regs->trapnum == 7) math_state_restore(); + + /* Restore SYSENTER if it's supposed to be on. */ + if (boot_cpu_has(X86_FEATURE_SEP)) + wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); } /*H:130 Now we've examined the hypercall code; our Guest can make requests. diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index ab6a61db63ce..835def11419d 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -432,7 +432,6 @@ static int crypt_convert(struct crypt_config *cc, case 0: atomic_dec(&ctx->pending); ctx->sector++; - cond_resched(); continue; /* error */ diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 2580ac1b9b0f..7cf512a34ccf 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -3897,10 +3897,8 @@ static void autorun_devices(int part) md_probe(dev, NULL, NULL); mddev = mddev_find(dev); - if (!mddev || !mddev->gendisk) { - if (mddev) - mddev_put(mddev); - printk(KERN_ERR + if (!mddev) { + printk(KERN_ERR "md: cannot allocate memory for md drive.\n"); break; } diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index a71277b640ab..1de17da34a95 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -2137,8 +2137,6 @@ static int run(mddev_t *mddev) !test_bit(In_sync, &disk->rdev->flags)) { disk->head_position = 0; mddev->degraded++; - if (disk->rdev) - conf->fullsync = 1; } } diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 54c8ee28fcc4..c37e256b1176 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2898,8 +2898,6 @@ static void handle_stripe5(struct stripe_head *sh) for (i = conf->raid_disks; i--; ) { set_bit(R5_Wantwrite, &sh->dev[i].flags); - set_bit(R5_LOCKED, &dev->flags); - s.locked++; if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending)) sh->ops.count++; } @@ -2913,7 +2911,6 @@ static void handle_stripe5(struct stripe_head *sh) conf->raid_disks); s.locked += handle_write_operations5(sh, 1, 1); } else if (s.expanded && - s.locked == 0 && !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) { clear_bit(STRIPE_EXPAND_READY, &sh->state); atomic_dec(&conf->reshape_stripes); @@ -4308,9 +4305,7 @@ static int run(mddev_t *mddev) " disk %d\n", bdevname(rdev->bdev,b), raid_disk); working_disks++; - } else - /* Cannot rely on bitmap to complete recovery */ - conf->fullsync = 1; + } } /* diff --git a/trunk/drivers/media/common/ir-keymaps.c b/trunk/drivers/media/common/ir-keymaps.c index 8fa91f846d59..a3485817e46c 100644 --- a/trunk/drivers/media/common/ir-keymaps.c +++ b/trunk/drivers/media/common/ir-keymaps.c @@ -2201,41 +2201,3 @@ IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = { [0x25] = KEY_POWER, /* power */ }; EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel); - -IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { - [0x20] = KEY_LIST, - [0x00] = KEY_POWER, - [0x28] = KEY_1, - [0x18] = KEY_2, - [0x38] = KEY_3, - [0x24] = KEY_4, - [0x14] = KEY_5, - [0x34] = KEY_6, - [0x2c] = KEY_7, - [0x1c] = KEY_8, - [0x3c] = KEY_9, - [0x12] = KEY_SUBTITLE, - [0x22] = KEY_0, - [0x32] = KEY_REWIND, - [0x3a] = KEY_SHUFFLE, - [0x02] = KEY_PRINT, - [0x11] = KEY_CHANNELDOWN, - [0x31] = KEY_CHANNELUP, - [0x0c] = KEY_ZOOM, - [0x1e] = KEY_VOLUMEDOWN, - [0x3e] = KEY_VOLUMEUP, - [0x0a] = KEY_MUTE, - [0x04] = KEY_AUDIO, - [0x26] = KEY_RECORD, - [0x06] = KEY_PLAY, - [0x36] = KEY_STOP, - [0x16] = KEY_PAUSE, - [0x2e] = KEY_REWIND, - [0x0e] = KEY_FASTFORWARD, - [0x30] = KEY_TEXT, - [0x21] = KEY_GREEN, - [0x01] = KEY_BLUE, - [0x08] = KEY_EPG, - [0x2a] = KEY_MENU, -}; -EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d); diff --git a/trunk/drivers/media/common/tuners/tda18271-common.c b/trunk/drivers/media/common/tuners/tda18271-common.c index 6fb5b4586569..f1894fec32b9 100644 --- a/trunk/drivers/media/common/tuners/tda18271-common.c +++ b/trunk/drivers/media/common/tuners/tda18271-common.c @@ -649,17 +649,9 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) u8 val; int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val); - /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range - * for frequencies above 61.1 MHz. In these cases, the internal RF - * tracking filters calibration mechanism is used. - * - * There is no need to warn the user about this. - */ - if (ret < 0) - goto fail; regs[R_EB14] = val; -fail: + return ret; } diff --git a/trunk/drivers/media/common/tuners/tda18271-fe.c b/trunk/drivers/media/common/tuners/tda18271-fe.c index 93063c6fbbf6..89c01fb1f859 100644 --- a/trunk/drivers/media/common/tuners/tda18271-fe.c +++ b/trunk/drivers/media/common/tuners/tda18271-fe.c @@ -45,21 +45,6 @@ static inline int charge_pump_source(struct dvb_frontend *fe, int force) TDA18271_MAIN_PLL, force); } -static inline void tda18271_set_if_notch(struct dvb_frontend *fe) -{ - struct tda18271_priv *priv = fe->tuner_priv; - unsigned char *regs = priv->tda18271_regs; - - switch (priv->mode) { - case TDA18271_ANALOG: - regs[R_MPD] &= ~0x80; /* IF notch = 0 */ - break; - case TDA18271_DIGITAL: - regs[R_MPD] |= 0x80; /* IF notch = 1 */ - break; - } -} - static int tda18271_channel_configuration(struct dvb_frontend *fe, struct tda18271_std_map_item *map, u32 freq, u32 bw) @@ -75,18 +60,25 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, regs[R_EP3] &= ~0x1f; /* clear std bits */ regs[R_EP3] |= (map->agc_mode << 3) | map->std; - if (priv->id == TDA18271HDC2) { - /* set rfagc to high speed mode */ - regs[R_EP3] &= ~0x04; - } + /* set rfagc to high speed mode */ + regs[R_EP3] &= ~0x04; /* set cal mode to normal */ regs[R_EP4] &= ~0x03; - /* update IF output level */ + /* update IF output level & IF notch frequency */ regs[R_EP4] &= ~0x1c; /* clear if level bits */ regs[R_EP4] |= (map->if_lvl << 2); + switch (priv->mode) { + case TDA18271_ANALOG: + regs[R_MPD] &= ~0x80; /* IF notch = 0 */ + break; + case TDA18271_DIGITAL: + regs[R_MPD] |= 0x80; /* IF notch = 1 */ + break; + } + /* update FM_RFn */ regs[R_EP4] &= ~0x80; regs[R_EP4] |= map->fm_rfn << 7; @@ -103,9 +95,6 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, /* disable Power Level Indicator */ regs[R_EP1] |= 0x40; - /* make sure thermometer is off */ - regs[R_TM] &= ~0x10; - /* frequency dependent parameters */ tda18271_calc_ir_measure(fe, &freq); @@ -146,7 +135,6 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, switch (priv->role) { case TDA18271_MASTER: tda18271_calc_main_pll(fe, N); - tda18271_set_if_notch(fe); tda18271_write_regs(fe, R_MPD, 4); break; case TDA18271_SLAVE: @@ -154,7 +142,6 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, tda18271_write_regs(fe, R_CPD, 4); regs[R_MPD] = regs[R_CPD] & 0x7f; - tda18271_set_if_notch(fe); tda18271_write_regs(fe, R_MPD, 1); break; } @@ -173,14 +160,12 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, msleep(20); - if (priv->id == TDA18271HDC2) { - /* set rfagc to normal speed mode */ - if (map->fm_rfn) - regs[R_EP3] &= ~0x04; - else - regs[R_EP3] |= 0x04; - ret = tda18271_write_regs(fe, R_EP3, 1); - } + /* set rfagc to normal speed mode */ + if (map->fm_rfn) + regs[R_EP3] &= ~0x04; + else + regs[R_EP3] |= 0x04; + ret = tda18271_write_regs(fe, R_EP3, 1); fail: return ret; } @@ -522,7 +507,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe) /* set cal mode to normal */ regs[R_EP4] &= ~0x03; - /* update IF output level */ + /* update IF output level & IF notch frequency */ regs[R_EP4] &= ~0x1c; /* clear if level bits */ ret = tda18271_write_regs(fe, R_EP3, 2); diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index 7cf4f5bdb2ec..ceae6db901ec 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -177,7 +177,6 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { {"FM Radio-INPUT1", 0x0208, 0x9002} }; -static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); static void xc5000_TunerReset(struct dvb_frontend *fe); @@ -353,7 +352,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, static int xc_shutdown(struct xc5000_priv *priv) { - return XC_RESULT_SUCCESS; + return 0; /* Fixme: cannot bring tuner back alive once shutdown * without reloading the driver modules. * return xc_write_reg(priv, XREG_POWER_DOWN, 0); @@ -686,25 +685,6 @@ static int xc5000_set_params(struct dvb_frontend *fe, return 0; } -static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) -{ - struct xc5000_priv *priv = fe->tuner_priv; - int ret; - u16 id; - - ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id); - if (ret == XC_RESULT_SUCCESS) { - if (id == XC_PRODUCT_ID_FW_NOT_LOADED) - ret = XC_RESULT_RESET_FAILURE; - else - ret = XC_RESULT_SUCCESS; - } - - dprintk(1, "%s() returns %s id = 0x%x\n", __func__, - ret == XC_RESULT_SUCCESS ? "True" : "False", id); - return ret; -} - static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); static int xc5000_set_analog_params(struct dvb_frontend *fe, @@ -713,7 +693,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, struct xc5000_priv *priv = fe->tuner_priv; int ret; - if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) + if(priv->fwloaded == 0) xc_load_fw_and_init_tuner(fe); dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", @@ -828,10 +808,11 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) struct xc5000_priv *priv = fe->tuner_priv; int ret = 0; - if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { + if (priv->fwloaded == 0) { ret = xc5000_fwupload(fe); if (ret != XC_RESULT_SUCCESS) return ret; + priv->fwloaded = 1; } /* Start the tuner self-calibration process */ @@ -871,6 +852,7 @@ static int xc5000_sleep(struct dvb_frontend *fe) return -EREMOTEIO; } else { + /* priv->fwloaded = 0; */ return XC_RESULT_SUCCESS; } } @@ -951,6 +933,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, cfg->i2c_address); printk(KERN_INFO "xc5000: Firmware has been loaded previously\n"); + priv->fwloaded = 1; break; case XC_PRODUCT_ID_FW_NOT_LOADED: printk(KERN_INFO @@ -958,6 +941,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, cfg->i2c_address); printk(KERN_INFO "xc5000: Firmware has not been loaded previously\n"); + priv->fwloaded = 0; break; default: printk(KERN_ERR diff --git a/trunk/drivers/media/common/tuners/xc5000_priv.h b/trunk/drivers/media/common/tuners/xc5000_priv.h index a72a9887fe7f..ecebfe4745ad 100644 --- a/trunk/drivers/media/common/tuners/xc5000_priv.h +++ b/trunk/drivers/media/common/tuners/xc5000_priv.h @@ -30,6 +30,7 @@ struct xc5000_priv { u32 bandwidth; u8 video_standard; u8 rf_mode; + u8 fwloaded; void *devptr; }; diff --git a/trunk/drivers/media/dvb/dvb-usb/gl861.c b/trunk/drivers/media/dvb/dvb-usb/gl861.c index 037f7ffb47b2..0a8ac64a4e33 100644 --- a/trunk/drivers/media/dvb/dvb-usb/gl861.c +++ b/trunk/drivers/media/dvb/dvb-usb/gl861.c @@ -47,8 +47,6 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, return -EINVAL; } - msleep(1); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, value, index, rbuf, rlen, 2000); } @@ -94,6 +92,16 @@ static struct i2c_algorithm gl861_i2c_algo = { }; /* Callbacks for DVB USB */ +static int gl861_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, + int *cold) +{ + *cold = 0; + + return 0; +} + static struct zl10353_config gl861_zl10353_config = { .demod_address = 0x0f, .no_tuner = 1, @@ -164,6 +172,7 @@ static struct dvb_usb_device_properties gl861_properties = { .size_of_priv = 0, + .identify_state = gl861_identify_state, .num_adapters = 1, .adapter = {{ @@ -185,15 +194,13 @@ static struct dvb_usb_device_properties gl861_properties = { .num_device_descs = 2, .devices = { - { - .name = "MSI Mega Sky 55801 DVB-T USB2.0", - .cold_ids = { NULL }, - .warm_ids = { &gl861_table[0], NULL }, + { "MSI Mega Sky 55801 DVB-T USB2.0", + { &gl861_table[0], NULL }, + { NULL }, }, - { - .name = "A-LINK DTU DVB-T USB2.0", - .cold_ids = { NULL }, - .warm_ids = { &gl861_table[1], NULL }, + { "A-LINK DTU DVB-T USB2.0", + { &gl861_table[1], NULL }, + { NULL }, }, } }; diff --git a/trunk/drivers/media/dvb/dvb-usb/umt-010.c b/trunk/drivers/media/dvb/dvb-usb/umt-010.c index 118aab1a3e54..9e7653bb3b66 100644 --- a/trunk/drivers/media/dvb/dvb-usb/umt-010.c +++ b/trunk/drivers/media/dvb/dvb-usb/umt-010.c @@ -107,7 +107,7 @@ static struct dvb_usb_device_properties umt_properties = { /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_BULK, - .count = MAX_NO_URBS_FOR_DATA_STREAM, + .count = 20, .endpoint = 0x06, .u = { .bulk = { diff --git a/trunk/drivers/media/dvb/frontends/au8522.c b/trunk/drivers/media/dvb/frontends/au8522.c index 03900d241a76..084a280c2d7f 100644 --- a/trunk/drivers/media/dvb/frontends/au8522.c +++ b/trunk/drivers/media/dvb/frontends/au8522.c @@ -463,13 +463,10 @@ static int au8522_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { struct au8522_state *state = fe->demodulator_priv; - int ret = -EINVAL; dprintk("%s(frequency=%d)\n", __func__, p->frequency); - if ((state->current_frequency == p->frequency) && - (state->current_modulation == p->u.vsb.modulation)) - return 0; + state->current_frequency = p->frequency; au8522_enable_modulation(fe, p->u.vsb.modulation); @@ -479,16 +476,11 @@ static int au8522_set_frontend(struct dvb_frontend *fe, if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - ret = fe->ops.tuner_ops.set_params(fe, p); + fe->ops.tuner_ops.set_params(fe, p); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); } - if (ret < 0) - return ret; - - state->current_frequency = p->frequency; - return 0; } @@ -506,16 +498,6 @@ static int au8522_init(struct dvb_frontend *fe) return 0; } -static int au8522_sleep(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - state->current_frequency = 0; - - return 0; -} - static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct au8522_state *state = fe->demodulator_priv; @@ -527,8 +509,10 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) if (state->current_modulation == VSB_8) { dprintk("%s() Checking VSB_8\n", __func__); reg = au8522_readreg(state, 0x4088); - if ((reg & 0x03) == 0x03) - *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; + if (reg & 0x01) + *status |= FE_HAS_VITERBI; + if (reg & 0x02) + *status |= FE_HAS_LOCK | FE_HAS_SYNC; } else { dprintk("%s() Checking QAM\n", __func__); reg = au8522_readreg(state, 0x4541); @@ -688,7 +672,6 @@ static struct dvb_frontend_ops au8522_ops = { }, .init = au8522_init, - .sleep = au8522_sleep, .i2c_gate_ctrl = au8522_i2c_gate_ctrl, .set_frontend = au8522_set_frontend, .get_frontend = au8522_get_frontend, diff --git a/trunk/drivers/media/dvb/frontends/stv0299.c b/trunk/drivers/media/dvb/frontends/stv0299.c index 35435bef8e79..17556183e871 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.c +++ b/trunk/drivers/media/dvb/frontends/stv0299.c @@ -63,7 +63,6 @@ struct stv0299_state { u32 symbol_rate; fe_code_rate_t fec_inner; int errmode; - u32 ucblocks; }; #define STATUS_BER 0 @@ -502,10 +501,8 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) { struct stv0299_state* state = fe->demodulator_priv; - if (state->errmode != STATUS_BER) - return -ENOSYS; - - *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8); + if (state->errmode != STATUS_BER) return 0; + *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); return 0; } @@ -543,12 +540,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) { struct stv0299_state* state = fe->demodulator_priv; - if (state->errmode != STATUS_UCBLOCKS) - return -ENOSYS; - - state->ucblocks += stv0299_readreg(state, 0x1e); - state->ucblocks += (stv0299_readreg(state, 0x1d) << 8); - *ucblocks = state->ucblocks; + if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0; + else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); return 0; } diff --git a/trunk/drivers/media/dvb/frontends/tda10023.c b/trunk/drivers/media/dvb/frontends/tda10023.c index c6ff5b82ff80..0727b80bc4d2 100644 --- a/trunk/drivers/media/dvb/frontends/tda10023.c +++ b/trunk/drivers/media/dvb/frontends/tda10023.c @@ -116,12 +116,9 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) int ret; ret = i2c_transfer (state->i2c, msg, 2); - if (ret != 2) { - int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error " - "(reg == 0x%02x, ret == %i)\n", - num, __func__, reg, ret); - } + if (ret != 2) + printk("DVB: TDA10023: %s: readreg error (ret == %i)\n", + __func__, ret); return b1[0]; } @@ -132,12 +129,11 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) int ret; ret = i2c_transfer (state->i2c, &msg, 1); - if (ret != 1) { - int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error " + if (ret != 1) + printk("DVB: TDA10023(%d): %s, writereg error " "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - num, __func__, reg, data, ret); - } + state->frontend.dvb->num, __func__, reg, data, ret); + return (ret != 1) ? -EREMOTEIO : 0; } @@ -468,7 +464,7 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, int i; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); + state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL); if (state == NULL) goto error; /* setup the state */ diff --git a/trunk/drivers/media/dvb/frontends/tda1004x.c b/trunk/drivers/media/dvb/frontends/tda1004x.c index a0d638653567..49973846373e 100644 --- a/trunk/drivers/media/dvb/frontends/tda1004x.c +++ b/trunk/drivers/media/dvb/frontends/tda1004x.c @@ -1248,14 +1248,11 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; - int id; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10045 state\n"); + if (!state) return NULL; - } /* setup the state */ state->config = config; @@ -1263,15 +1260,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ - id = tda1004x_read_byte(state, TDA1004X_CHIPID); - if (id < 0) { - printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n"); - kfree(state); - return NULL; - } - - if (id != 0x25) { - printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); + if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) { kfree(state); return NULL; } @@ -1318,14 +1307,11 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; - int id; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10046 state\n"); + if (!state) return NULL; - } /* setup the state */ state->config = config; @@ -1333,14 +1319,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ - id = tda1004x_read_byte(state, TDA1004X_CHIPID); - if (id < 0) { - printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n"); - kfree(state); - return NULL; - } - if (id != 0x46) { - printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); + if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { kfree(state); return NULL; } diff --git a/trunk/drivers/media/dvb/ttpci/Kconfig b/trunk/drivers/media/dvb/ttpci/Kconfig index 07643e010093..d4339b1b3b68 100644 --- a/trunk/drivers/media/dvb/ttpci/Kconfig +++ b/trunk/drivers/media/dvb/ttpci/Kconfig @@ -101,7 +101,6 @@ config DVB_BUDGET config DVB_BUDGET_CI tristate "Budget cards with onboard CI connector" depends on DVB_BUDGET_CORE && I2C - depends on INPUT # due to IR select DVB_STV0297 if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE diff --git a/trunk/drivers/media/dvb/ttpci/av7110_hw.c b/trunk/drivers/media/dvb/ttpci/av7110_hw.c index 3a3f5279e927..9d81074b31df 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_hw.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_hw.c @@ -427,7 +427,6 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) if (err) { printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", __func__, type); - av7110->arm_errors++; return -ETIMEDOUT; } msleep(1); @@ -854,8 +853,10 @@ static osd_raw_window_t bpp2bit[8] = { static inline int WaitUntilBmpLoaded(struct av7110 *av7110) { - int ret = wait_event_timeout(av7110->bmpq, + int ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, 10*HZ); + if (ret == -ERESTARTSYS) + return ret; if (ret == 0) { printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n", ret, av7110->bmp_state); diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 5ccb0aeca8cc..3b26fbd3e558 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -793,14 +793,6 @@ menuconfig V4L_USB_DRIVERS if V4L_USB_DRIVERS && USB -config USB_VIDEO_CLASS - tristate "USB Video Class (UVC)" - ---help--- - Support for the USB Video Class (UVC). Currently only video - input devices, such as webcams, are supported. - - For more information see: - source "drivers/media/video/pvrusb2/Kconfig" source "drivers/media/video/em28xx/Kconfig" diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index ecbbfaab24d5..dff0d6abe917 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -136,8 +136,6 @@ obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_VIDEO_AU0828) += au0828/ -obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ - EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/trunk/drivers/media/video/au0828/au0828-cards.c b/trunk/drivers/media/video/au0828/au0828-cards.c index 898e12395e7c..a2a6983444fa 100644 --- a/trunk/drivers/media/video/au0828/au0828-cards.c +++ b/trunk/drivers/media/video/au0828/au0828-cards.c @@ -77,14 +77,8 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) /* Make sure we support the board model */ switch (tv.model) { - case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */ case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ - case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ - case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ - case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */ - case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */ case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ - case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ break; default: printk(KERN_WARNING "%s: warning: " @@ -181,18 +175,6 @@ struct usb_device_id au0828_usb_id_table [] = { .driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 }, { USB_DEVICE(0x0fe9, 0xd620), .driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 }, - { USB_DEVICE(0x2040, 0x7210), - .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, - { USB_DEVICE(0x2040, 0x7217), - .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, - { USB_DEVICE(0x2040, 0x721b), - .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, - { USB_DEVICE(0x2040, 0x721f), - .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, - { USB_DEVICE(0x2040, 0x7280), - .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, - { USB_DEVICE(0x0fd9, 0x0008), - .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { }, }; diff --git a/trunk/drivers/media/video/cx18/Kconfig b/trunk/drivers/media/video/cx18/Kconfig index 9aefdc5ea79a..5f942690570c 100644 --- a/trunk/drivers/media/video/cx18/Kconfig +++ b/trunk/drivers/media/video/cx18/Kconfig @@ -10,8 +10,8 @@ config VIDEO_CX18 select VIDEO_TVEEPROM select VIDEO_CX2341X select VIDEO_CS5345 - select DVB_S5H1409 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE + select DVB_S5H1409 + select MEDIA_TUNER_MXL5005S ---help--- This is a video4linux driver for Conexant cx23418 based PCI combo video recorder devices. diff --git a/trunk/drivers/media/video/cx18/cx18-av-core.c b/trunk/drivers/media/video/cx18/cx18-av-core.c index faca43eb940f..9a26751615c6 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-core.c +++ b/trunk/drivers/media/video/cx18/cx18-av-core.c @@ -69,58 +69,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, or_value); } -int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask) -{ - int retval; - u32 saved_reg[8] = {0}; - - if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { - saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL); - saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { - saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1); - saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_VID) { - saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL); - saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL); - saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG); - saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG); - } - - retval = cx18_av_write(cx, addr, value); - - if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { - cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]); - cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { - cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]); - cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_VID) { - cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]); - cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]); - cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]); - cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]); - } - - return retval; -} - -int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask, - u8 or_value, int no_acfg_mask) -{ - return cx18_av_write_no_acfg(cx, addr, - (cx18_av_read(cx, addr) & and_mask) | - or_value, no_acfg_mask); -} - /* ----------------------------------------------------------------------- */ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, @@ -222,15 +170,13 @@ static void input_change(struct cx18 *cx) /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ if (std & V4L2_STD_SECAM) - cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL); + cx18_av_write(cx, 0x402, 0); else { - cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL); + cx18_av_write(cx, 0x402, 0x04); cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); } - cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0, - CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); - cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60, - CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); + cx18_av_and_or(cx, 0x401, ~0x60, 0); + cx18_av_and_or(cx, 0x401, ~0x60, 0x60); if (std & V4L2_STD_525_60) { if (std == V4L2_STD_NTSC_M_JP) { @@ -282,7 +228,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, if ((vid_input & ~0xff0) || luma < CX18_AV_SVIDEO_LUMA1 || - luma > CX18_AV_SVIDEO_LUMA8 || + luma > CX18_AV_SVIDEO_LUMA4 || chroma < CX18_AV_SVIDEO_CHROMA4 || chroma > CX18_AV_SVIDEO_CHROMA8) { CX18_ERR("0x%04x is not a valid video input!\n", @@ -316,8 +262,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, cx18_av_write(cx, 0x103, reg); /* Set INPUT_MODE to Composite (0) or S-Video (1) */ - cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02, - CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); + cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ @@ -373,12 +318,12 @@ static int set_v4lstd(struct cx18 *cx) This happens for example with the Yuan MPC622. */ if (fmt >= 4 && fmt < 8) { /* Set format to NTSC-M */ - cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE); + cx18_av_and_or(cx, 0x400, ~0xf, 1); /* Turn off LCOMB */ cx18_av_and_or(cx, 0x47b, ~6, 0); } - cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE); - cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL); + cx18_av_and_or(cx, 0x400, ~0xf, fmt); + cx18_av_and_or(cx, 0x403, ~0x3, pal_m); cx18_av_vbi_setup(cx); input_change(cx); return 0; diff --git a/trunk/drivers/media/video/cx18/cx18-av-core.h b/trunk/drivers/media/video/cx18/cx18-av-core.h index c172823ce1d8..786901d72e9a 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-core.h +++ b/trunk/drivers/media/video/cx18/cx18-av-core.h @@ -37,16 +37,12 @@ enum cx18_av_video_input { CX18_AV_COMPOSITE7, CX18_AV_COMPOSITE8, - /* S-Video inputs consist of one luma input (In1-In8) ORed with one + /* S-Video inputs consist of one luma input (In1-In4) ORed with one chroma input (In5-In8) */ CX18_AV_SVIDEO_LUMA1 = 0x10, CX18_AV_SVIDEO_LUMA2 = 0x20, CX18_AV_SVIDEO_LUMA3 = 0x30, CX18_AV_SVIDEO_LUMA4 = 0x40, - CX18_AV_SVIDEO_LUMA5 = 0x50, - CX18_AV_SVIDEO_LUMA6 = 0x60, - CX18_AV_SVIDEO_LUMA7 = 0x70, - CX18_AV_SVIDEO_LUMA8 = 0x80, CX18_AV_SVIDEO_CHROMA4 = 0x400, CX18_AV_SVIDEO_CHROMA5 = 0x500, CX18_AV_SVIDEO_CHROMA6 = 0x600, @@ -295,24 +291,14 @@ struct cx18_av_state { #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ -/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/ -#define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */ -#define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */ -#define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */ -#define CXADEC_NO_ACFG_ALL 0x07 - /* ----------------------------------------------------------------------- */ /* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); -int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, - int no_acfg_mask); u8 cx18_av_read(struct cx18 *cx, u16 addr); u32 cx18_av_read4(struct cx18 *cx, u16 addr); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); -int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value, - int no_acfg_mask); int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); /* ----------------------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/cx18/cx18-cards.c b/trunk/drivers/media/video/cx18/cx18-cards.c index c26e0ef5b075..baccd079243d 100644 --- a/trunk/drivers/media/video/cx18/cx18-cards.c +++ b/trunk/drivers/media/video/cx18/cx18-cards.c @@ -23,7 +23,6 @@ #include "cx18-driver.h" #include "cx18-cards.h" -#include "cx18-av-core.h" #include "cx18-i2c.h" #include @@ -55,22 +54,22 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, - { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, + { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, + CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, + CX23418_AUDIO_SERIAL, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, + CX23418_AUDIO_SERIAL, CS5345_IN_2 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, + CX23418_AUDIO_SERIAL, 0 }, .ddr = { /* ESMT M13S128324A-5B memory */ .chip_config = 0x003, @@ -82,11 +81,6 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { }, .gpio_init.initial_value = 0x3001, .gpio_init.direction = 0x3001, - .gpio_i2c_slave_reset = { - .active_lo_mask = 0x3001, - .msecs_asserted = 10, - .msecs_recovery = 40, - }, .i2c = &cx18_i2c_std, }; @@ -100,22 +94,22 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345 | CX18_HW_DVB, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, - { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, + { CX18_CARD_INPUT_SVIDEO2, 2, CX23418_SVIDEO2 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, + CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, + CX23418_AUDIO_SERIAL, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, + CX23418_AUDIO_SERIAL, CS5345_IN_2 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, + CX23418_AUDIO_SERIAL, 0 }, .ddr = { /* Samsung K4D263238G-VC33 memory */ .chip_config = 0x003, @@ -127,11 +121,6 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { }, .gpio_init.initial_value = 0x3001, .gpio_init.direction = 0x3001, - .gpio_i2c_slave_reset = { - .active_lo_mask = 0x3001, - .msecs_asserted = 10, - .msecs_recovery = 40, - }, .i2c = &cx18_i2c_std, }; @@ -152,19 +141,19 @@ static const struct cx18_card cx18_card_h900 = { .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 }, { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, + CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 }, }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO8, 0 }, + CX23418_AUDIO8, 0 }, { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL, 0 }, + CX23418_AUDIO_SERIAL, 0 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, 0 }, + CX23418_AUDIO_SERIAL, 0 }, .tuners = { { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, }, @@ -194,26 +183,23 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = { static const struct cx18_card cx18_card_mpc718 = { .type = CX18_CARD_YUAN_MPC718, .name = "Yuan MPC718", - .comment = "Some Composite and S-Video inputs are currently working.\n", - .v4l2_capabilities = CX18_CAP_ENCODER, + .comment = "Not yet supported!\n", + .v4l2_capabilities = 0, .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, - { CX18_CARD_INPUT_SVIDEO2, 2, - CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, - { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 }, + { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 }, + { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 }, - { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, + CX23418_AUDIO8, 0 }, + { CX18_CARD_INPUT_LINE_IN1, + CX23418_AUDIO_SERIAL, 0 }, }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, + CX23418_AUDIO_SERIAL, 0 }, .tuners = { /* XC3028 tuner */ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, diff --git a/trunk/drivers/media/video/cx18/cx18-cards.h b/trunk/drivers/media/video/cx18/cx18-cards.h index dc2dd945d4c3..bccb67f0db16 100644 --- a/trunk/drivers/media/video/cx18/cx18-cards.h +++ b/trunk/drivers/media/video/cx18/cx18-cards.h @@ -36,6 +36,36 @@ #define CX18_CARD_INPUT_COMPOSITE2 5 #define CX18_CARD_INPUT_COMPOSITE3 6 +enum cx34180_video_input { + /* Composite video inputs In1-In8 */ + CX23418_COMPOSITE1 = 1, + CX23418_COMPOSITE2, + CX23418_COMPOSITE3, + CX23418_COMPOSITE4, + CX23418_COMPOSITE5, + CX23418_COMPOSITE6, + CX23418_COMPOSITE7, + CX23418_COMPOSITE8, + + /* S-Video inputs consist of one luma input (In1-In4) ORed with one + chroma input (In5-In8) */ + CX23418_SVIDEO_LUMA1 = 0x10, + CX23418_SVIDEO_LUMA2 = 0x20, + CX23418_SVIDEO_LUMA3 = 0x30, + CX23418_SVIDEO_LUMA4 = 0x40, + CX23418_SVIDEO_CHROMA4 = 0x400, + CX23418_SVIDEO_CHROMA5 = 0x500, + CX23418_SVIDEO_CHROMA6 = 0x600, + CX23418_SVIDEO_CHROMA7 = 0x700, + CX23418_SVIDEO_CHROMA8 = 0x800, + + /* S-Video aliases for common luma/chroma combinations */ + CX23418_SVIDEO1 = 0x510, + CX23418_SVIDEO2 = 0x620, + CX23418_SVIDEO3 = 0x730, + CX23418_SVIDEO4 = 0x840, +}; + /* audio inputs */ #define CX18_CARD_INPUT_AUD_TUNER 1 #define CX18_CARD_INPUT_LINE_IN1 2 @@ -45,6 +75,16 @@ #define CX18_CARD_MAX_AUDIO_INPUTS 3 #define CX18_CARD_MAX_TUNERS 2 +enum cx23418_audio_input { + /* Audio inputs: serial or In4-In8 */ + CX23418_AUDIO_SERIAL, + CX23418_AUDIO4 = 4, + CX23418_AUDIO5, + CX23418_AUDIO6, + CX23418_AUDIO7, + CX23418_AUDIO8, +}; + /* V4L2 capability aliases */ #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE) @@ -78,13 +118,6 @@ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */ u32 initial_value; }; -struct cx18_gpio_i2c_slave_reset { - u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */ - u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ - int msecs_asserted; /* time period reset must remain asserted */ - int msecs_recovery; /* time after deassert for chips to be ready */ -}; - struct cx18_card_tuner { v4l2_std_id std; /* standard for which the tuner is suitable */ int tuner; /* tuner ID (from tuner.h) */ @@ -121,8 +154,7 @@ struct cx18_card { /* GPIO card-specific settings */ u8 xceive_pin; /* XCeive tuner GPIO reset pin */ - struct cx18_gpio_init gpio_init; - struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset; + struct cx18_gpio_init gpio_init; struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; struct cx18_card_tuner_i2c *i2c; diff --git a/trunk/drivers/media/video/cx18/cx18-dvb.c b/trunk/drivers/media/video/cx18/cx18-dvb.c index cae38985b131..c9744173f969 100644 --- a/trunk/drivers/media/video/cx18/cx18-dvb.c +++ b/trunk/drivers/media/video/cx18/cx18-dvb.c @@ -69,21 +69,11 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) struct dvb_demux *demux = feed->demux; struct cx18_stream *stream = (struct cx18_stream *) demux->priv; struct cx18 *cx = stream->cx; - int ret; + int ret = -EINVAL; u32 v; CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", feed->pid, feed->index); - - mutex_lock(&cx->serialize_lock); - ret = cx18_init_on_first_open(cx); - mutex_unlock(&cx->serialize_lock); - if (ret) { - CX18_ERR("Failed to initialize firmware starting DVB feed\n"); - return ret; - } - ret = -EINVAL; - switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: @@ -111,11 +101,6 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) if (stream->dvb.feeding++ == 0) { CX18_DEBUG_INFO("Starting Transport DMA\n"); ret = cx18_start_v4l2_encode_stream(stream); - if (ret < 0) { - CX18_DEBUG_INFO( - "Failed to start Transport DMA\n"); - stream->dvb.feeding--; - } } else ret = 0; mutex_unlock(&stream->dvb.feedlock); diff --git a/trunk/drivers/media/video/cx18/cx18-gpio.c b/trunk/drivers/media/video/cx18/cx18-gpio.c index b302833f6f9d..ceb63653c926 100644 --- a/trunk/drivers/media/video/cx18/cx18-gpio.c +++ b/trunk/drivers/media/video/cx18/cx18-gpio.c @@ -53,34 +53,10 @@ static void gpio_write(struct cx18 *cx) write_reg(((dir & 0xffff) << 16) | (val & 0xffff), CX18_REG_GPIO_OUT1); write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); - write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), + write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), CX18_REG_GPIO_OUT2); } -void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) -{ - const struct cx18_gpio_i2c_slave_reset *p; - - p = &cx->card->gpio_i2c_slave_reset; - - if ((p->active_lo_mask | p->active_hi_mask) == 0) - return; - - /* Assuming that the masks are a subset of the bits in gpio_dir */ - - /* Assert */ - cx->gpio_val = - (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); - gpio_write(cx); - schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); - - /* Deassert */ - cx->gpio_val = - (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); - gpio_write(cx); - schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); -} - void cx18_gpio_init(struct cx18 *cx) { cx->gpio_dir = cx->card->gpio_init.direction; diff --git a/trunk/drivers/media/video/cx18/cx18-gpio.h b/trunk/drivers/media/video/cx18/cx18-gpio.h index 525c328f748a..41bac8856b50 100644 --- a/trunk/drivers/media/video/cx18/cx18-gpio.h +++ b/trunk/drivers/media/video/cx18/cx18-gpio.h @@ -21,5 +21,4 @@ */ void cx18_gpio_init(struct cx18 *cx); -void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); int cx18_reset_tuner_gpio(void *dev, int cmd, int value); diff --git a/trunk/drivers/media/video/cx18/cx18-i2c.c b/trunk/drivers/media/video/cx18/cx18-i2c.c index 680bc4e35b79..1d6c51a75313 100644 --- a/trunk/drivers/media/video/cx18/cx18-i2c.c +++ b/trunk/drivers/media/video/cx18/cx18-i2c.c @@ -405,8 +405,6 @@ int init_cx18_i2c(struct cx18 *cx) cx18_setscl(&cx->i2c_algo_cb_data[1], 1); cx18_setsda(&cx->i2c_algo_cb_data[1], 1); - cx18_reset_i2c_slaves_gpio(cx); - return i2c_bit_add_bus(&cx->i2c_adap[0]) || i2c_bit_add_bus(&cx->i2c_adap[1]); } diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.c b/trunk/drivers/media/video/cx25840/cx25840-core.c index 1da6f134888d..607efdcd22f8 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.c +++ b/trunk/drivers/media/video/cx25840/cx25840-core.c @@ -433,7 +433,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp int chroma = vid_input & 0xf00; if ((vid_input & ~0xff0) || - luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 || + luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 || chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { v4l_err(client, "0x%04x is not a valid video input!\n", vid_input); diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c index 80c8883e54b5..e976fc6bef7c 100644 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ b/trunk/drivers/media/video/cx88/cx88-alsa.c @@ -332,12 +332,6 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int err; - if (!chip) { - printk(KERN_ERR "BUG: cx88 can't find device struct." - " Can't proceed with open\n"); - return -ENODEV; - } - err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) goto _error; diff --git a/trunk/drivers/media/video/em28xx/em28xx-audio.c b/trunk/drivers/media/video/em28xx/em28xx-audio.c index 3c006103c1eb..92b2a6db4fdc 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-audio.c +++ b/trunk/drivers/media/video/em28xx/em28xx-audio.c @@ -268,12 +268,6 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) dprintk("opening device and trying to acquire exclusive lock\n"); - if (!dev) { - printk(KERN_ERR "BUG: em28xx can't find device struct." - " Can't proceed with open\n"); - return -ENODEV; - } - /* Sets volume, mute, etc */ dev->mute = 0; @@ -421,12 +415,6 @@ static int em28xx_audio_init(struct em28xx *dev) static int devnr; int ret, err; - if (dev->has_audio_class) { - /* This device does not support the extension (in this case - the device is expecting the snd-usb-audio module */ - return 0; - } - printk(KERN_INFO "em28xx-audio.c: probing for em28x1 " "non standard usbaudio\n"); printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " @@ -470,12 +458,6 @@ static int em28xx_audio_fini(struct em28xx *dev) if (dev == NULL) return 0; - if (dev->has_audio_class) { - /* This device does not support the extension (in this case - the device is expecting the snd-usb-audio module */ - return 0; - } - if (dev->adev) { snd_card_free(dev->adev->sndcard); kfree(dev->adev); diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index 8cbda43727c3..3e4f3c7e92e7 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -157,7 +157,6 @@ struct em28xx_board em28xx_boards[] = { .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .mts_firmware = 1, - .has_dvb = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -525,9 +524,6 @@ void em28xx_pre_card_setup(struct em28xx *dev) rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); if (rc > 0) { switch (rc) { - case CHIP_ID_EM2860: - em28xx_info("chip ID is em2860\n"); - break; case CHIP_ID_EM2883: em28xx_info("chip ID is em2882/em2883\n"); dev->wait_after_write = 0; diff --git a/trunk/drivers/media/video/em28xx/em28xx-dvb.c b/trunk/drivers/media/video/em28xx/em28xx-dvb.c index 0b2333ee07f8..8cf4983f0039 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-dvb.c +++ b/trunk/drivers/media/video/em28xx/em28xx-dvb.c @@ -382,11 +382,6 @@ static int dvb_init(struct em28xx *dev) int result = 0; struct em28xx_dvb *dvb; - if (!dev->has_dvb) { - /* This device does not support the extension */ - return 0; - } - dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { @@ -449,11 +444,6 @@ static int dvb_init(struct em28xx *dev) static int dvb_fini(struct em28xx *dev) { - if (!dev->has_dvb) { - /* This device does not support the extension */ - return 0; - } - if (dev->dvb) { unregister_dvb(dev->dvb); dev->dvb = NULL; diff --git a/trunk/drivers/media/video/em28xx/em28xx-reg.h b/trunk/drivers/media/video/em28xx/em28xx-reg.h index fac1ab23f621..9058bed07953 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-reg.h +++ b/trunk/drivers/media/video/em28xx/em28xx-reg.h @@ -84,6 +84,5 @@ /* FIXME: Need to be populated with the other chip ID's */ enum em28xx_chip_id { - CHIP_ID_EM2860 = 34, CHIP_ID_EM2883 = 36, }; diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index 285bc62bbe46..fb163ecd9216 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -1848,28 +1848,32 @@ static DEFINE_MUTEX(em28xx_extension_devlist_lock); int em28xx_register_extension(struct em28xx_ops *ops) { - struct em28xx *dev = NULL; + struct em28xx *h, *dev = NULL; + + list_for_each_entry(h, &em28xx_devlist, devlist) + dev = h; mutex_lock(&em28xx_extension_devlist_lock); list_add_tail(&ops->next, &em28xx_extension_devlist); - list_for_each_entry(dev, &em28xx_devlist, devlist) { - if (dev) - ops->init(dev); - } + if (dev) + ops->init(dev); + printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); mutex_unlock(&em28xx_extension_devlist_lock); + return 0; } EXPORT_SYMBOL(em28xx_register_extension); void em28xx_unregister_extension(struct em28xx_ops *ops) { - struct em28xx *dev = NULL; + struct em28xx *h, *dev = NULL; - list_for_each_entry(dev, &em28xx_devlist, devlist) { - if (dev) - ops->fini(dev); - } + list_for_each_entry(h, &em28xx_devlist, devlist) + dev = h; + + if (dev) + ops->fini(dev); mutex_lock(&em28xx_extension_devlist_lock); printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); diff --git a/trunk/drivers/media/video/pxa_camera.c b/trunk/drivers/media/video/pxa_camera.c index 5ec5bb9a94d2..7cc8e9b19fb7 100644 --- a/trunk/drivers/media/video/pxa_camera.c +++ b/trunk/drivers/media/video/pxa_camera.c @@ -1019,12 +1019,12 @@ static int pxa_camera_probe(struct platform_device *pdev) struct pxa_camera_dev *pcdev; struct resource *res; void __iomem *base; - int irq; + unsigned int irq; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!res || irq < 0) { + if (!res || !irq) { err = -ENODEV; goto exit; } diff --git a/trunk/drivers/media/video/saa7134/saa7134-alsa.c b/trunk/drivers/media/video/saa7134/saa7134-alsa.c index f118de6e3672..ba3082422a01 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-alsa.c +++ b/trunk/drivers/media/video/saa7134/saa7134-alsa.c @@ -613,15 +613,9 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) struct snd_pcm_runtime *runtime = substream->runtime; snd_card_saa7134_pcm_t *pcm; snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); - struct saa7134_dev *dev; + struct saa7134_dev *dev = saa7134->dev; int amux, err; - if (!saa7134) { - printk(KERN_ERR "BUG: saa7134 can't find device struct." - " Can't proceed with open\n"); - return -ENODEV; - } - dev = saa7134->dev; mutex_lock(&dev->dmasound.lock); dev->dmasound.read_count = 0; diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index 2618cfa592e7..b111903aa322 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -4114,7 +4114,11 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + /* + TODO: .mpeg = SAA7134_MPEG_DVB, + */ + .inputs = {{ .name = name_tv, .vmux = 1, @@ -4153,7 +4157,7 @@ struct saa7134_board saa7134_boards[] = { } }, .radio = { .name = name_radio, - .amux = TV, + .amux = LINE1, }, }, [SAA7134_BOARD_AVERMEDIA_M115] = { @@ -4163,7 +4167,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, .vmux = 1, @@ -5348,21 +5351,22 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev, { switch (command) { case XC2028_TUNER_RESET: - saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00000000); - saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000); - switch (dev->board) { - case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: - saa7134_set_gpio(dev, 23, 0); - msleep(10); - saa7134_set_gpio(dev, 23, 1); - break; - case SAA7134_BOARD_AVERMEDIA_A16D: - saa7134_set_gpio(dev, 21, 0); - msleep(10); - saa7134_set_gpio(dev, 21, 1); - break; - } - return 0; + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000); + saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000); + mdelay(250); + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0); + saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0); + mdelay(250); + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000); + saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000); + mdelay(250); + saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02); + saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81); + saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7); + saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03); + saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2, + 0x0001e000, 0x0001e000); + return 0; } return -EINVAL; } @@ -5549,7 +5553,9 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS: + case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: case SAA7134_BOARD_AVERMEDIA_M115: + case SAA7134_BOARD_AVERMEDIA_A16D: /* power-down tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0); @@ -5559,18 +5565,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); msleep(10); break; - case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: - saa7134_set_gpio(dev, 23, 0); - msleep(10); - saa7134_set_gpio(dev, 23, 1); - break; - case SAA7134_BOARD_AVERMEDIA_A16D: - saa7134_set_gpio(dev, 21, 0); - msleep(10); - saa7134_set_gpio(dev, 21, 1); - msleep(1); - dev->has_remote = SAA7134_REMOTE_GPIO; - break; case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: /* power-down tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x000A8004, 0x000A8004); @@ -5621,8 +5615,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100); printk("%s: %s: hybrid analog/dvb card\n" - "%s: Sorry, only analog s-video and composite input " - "are supported for now.\n", + "%s: Sorry, only the analog inputs are supported for now.\n", dev->name, card(dev).name, dev->name); break; } @@ -5682,7 +5675,6 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_AVERMEDIA_A16D: - case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: ctl.demod = XC3028_FE_ZARLINK456; break; default: diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 341b101b0357..469f93aac008 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -153,12 +153,12 @@ static int mt352_aver777_init(struct dvb_frontend* fe) return 0; } -static int mt352_avermedia_xc3028_init(struct dvb_frontend *fe) +static int mt352_aver_a16d_init(struct dvb_frontend *fe) { - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d }; - static u8 reset [] = { RESET, 0x80 }; - static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static u8 agc_cfg [] = { AGC_TARGET, 0xe }; + static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x2d }; + static u8 reset [] = { RESET, 0x80 }; + static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; + static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 }; static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 }; mt352_write(fe, clock_config, sizeof(clock_config)); @@ -167,9 +167,12 @@ static int mt352_avermedia_xc3028_init(struct dvb_frontend *fe) mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); mt352_write(fe, agc_cfg, sizeof(agc_cfg)); mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); + return 0; } + + static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { @@ -212,10 +215,14 @@ static struct mt352_config avermedia_777 = { .demod_init = mt352_aver777_init, }; -static struct mt352_config avermedia_xc3028_mt352_dev = { +static struct mt352_config avermedia_16d = { + .demod_address = 0xf, + .demod_init = mt352_aver_a16d_init, +}; + +static struct mt352_config avermedia_e506r_mt352_dev = { .demod_address = (0x1e >> 1), .no_tuner = 1, - .demod_init = mt352_avermedia_xc3028_init, }; /* ================================================================== @@ -968,10 +975,9 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_AVERMEDIA_A16D: - dprintk("AverMedia A16D dvb setup\n"); - dev->dvb.frontend = dvb_attach(mt352_attach, - &avermedia_xc3028_mt352_dev, - &dev->i2c_adap); + dprintk("avertv A16D dvb setup\n"); + dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_16d, + &dev->i2c_adap); attach_xc3028 = 1; break; case SAA7134_BOARD_MD7134: @@ -1085,8 +1091,7 @@ static int dvb_init(struct saa7134_dev *dev) ads_tech_duo_config.tuner_address); goto dettach_frontend; } - } else - wprintk("failed to attach tda10046\n"); + } break; case SAA7134_BOARD_TEVION_DVBT_220RF: if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config, @@ -1255,14 +1260,11 @@ static int dvb_init(struct saa7134_dev *dev) goto dettach_frontend; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: - dprintk("AverMedia E506R dvb setup\n"); - saa7134_set_gpio(dev, 25, 0); - msleep(10); - saa7134_set_gpio(dev, 25, 1); dev->dvb.frontend = dvb_attach(mt352_attach, - &avermedia_xc3028_mt352_dev, - &dev->i2c_adap); + &avermedia_e506r_mt352_dev, + &dev->i2c_adap); attach_xc3028 = 1; + break; case SAA7134_BOARD_MD7134_BRIDGE_2: dev->dvb.frontend = dvb_attach(tda10086_attach, &sd1878_4m, &dev->i2c_adap); @@ -1336,8 +1338,7 @@ static int dvb_init(struct saa7134_dev *dev) return ret; dettach_frontend: - if (dev->dvb.frontend) - dvb_frontend_detach(dev->dvb.frontend); + dvb_frontend_detach(dev->dvb.frontend); dev->dvb.frontend = NULL; return -1; diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index 3ae71a340822..81431ee41842 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -110,10 +110,9 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.vb_lock); - videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); + dev->empress_users--; /* stop the encoder */ ts_reset_encoder(dev); @@ -122,10 +121,6 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - dev->empress_users--; - - mutex_unlock(&dev->empress_tsq.vb_lock); - return 0; } @@ -223,7 +218,8 @@ static int empress_enum_fmt_cap(struct file *file, void *priv, static int empress_g_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f); @@ -236,7 +232,8 @@ static int empress_g_fmt_cap(struct file *file, void *priv, static int empress_s_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f); @@ -250,7 +247,8 @@ static int empress_s_fmt_cap(struct file *file, void *priv, static int empress_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; return videobuf_reqbufs(&dev->empress_tsq, p); } @@ -258,21 +256,24 @@ static int empress_reqbufs(struct file *file, void *priv, static int empress_querybuf(struct file *file, void *priv, struct v4l2_buffer *b) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; return videobuf_querybuf(&dev->empress_tsq, b); } static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; return videobuf_qbuf(&dev->empress_tsq, b); } static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; return videobuf_dqbuf(&dev->empress_tsq, b, file->f_flags & O_NONBLOCK); @@ -281,7 +282,8 @@ static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) static int empress_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; return videobuf_streamon(&dev->empress_tsq); } @@ -289,7 +291,8 @@ static int empress_streamon(struct file *file, void *priv, static int empress_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; return videobuf_streamoff(&dev->empress_tsq); } @@ -297,7 +300,8 @@ static int empress_streamoff(struct file *file, void *priv, static int empress_s_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; /* count == 0 is abused in saa6752hs.c, so that special case is handled here explicitly. */ @@ -316,7 +320,8 @@ static int empress_s_ext_ctrls(struct file *file, void *priv, static int empress_g_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; diff --git a/trunk/drivers/media/video/saa7134/saa7134-input.c b/trunk/drivers/media/video/saa7134/saa7134-input.c index 76e6501d238d..919632b10aae 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-input.c +++ b/trunk/drivers/media/video/saa7134/saa7134-input.c @@ -323,15 +323,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) saa_setb(SAA7134_GPIO_GPMODE1, 0x1); saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); break; - case SAA7134_BOARD_AVERMEDIA_A16D: - ir_codes = ir_codes_avermedia_a16d; - mask_keycode = 0x02F200; - mask_keydown = 0x000400; - polling = 50; /* ms */ - /* Without this we won't receive key up events */ - saa_setb(SAA7134_GPIO_GPMODE1, 0x1); - saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1); - break; case SAA7134_BOARD_KWORLD_TERMINATOR: ir_codes = ir_codes_pixelview; mask_keycode = 0x00001f; diff --git a/trunk/drivers/media/video/soc_camera.c b/trunk/drivers/media/video/soc_camera.c index d015bfe00950..a1b92446c8b4 100644 --- a/trunk/drivers/media/video/soc_camera.c +++ b/trunk/drivers/media/video/soc_camera.c @@ -763,6 +763,15 @@ static struct device_driver ic_drv = { .owner = THIS_MODULE, }; +/* + * Image capture host - this is a host device, not a bus device, so, + * no bus reference, no probing. + */ +static struct class soc_camera_host_class = { + .owner = THIS_MODULE, + .name = "camera_host", +}; + static void dummy_release(struct device *dev) { } @@ -792,6 +801,7 @@ int soc_camera_host_register(struct soc_camera_host *ici) /* Number might be equal to the platform device ID */ sprintf(ici->dev.bus_id, "camera_host%d", ici->nr); + ici->dev.class = &soc_camera_host_class; mutex_lock(&list_lock); list_for_each_entry(ix, &hosts, list) { @@ -993,9 +1003,14 @@ static int __init soc_camera_init(void) ret = driver_register(&ic_drv); if (ret) goto edrvr; + ret = class_register(&soc_camera_host_class); + if (ret) + goto eclr; return 0; +eclr: + driver_unregister(&ic_drv); edrvr: bus_unregister(&soc_camera_bus_type); return ret; @@ -1003,6 +1018,7 @@ static int __init soc_camera_init(void) static void __exit soc_camera_exit(void) { + class_unregister(&soc_camera_host_class); driver_unregister(&ic_drv); bus_unregister(&soc_camera_bus_type); } diff --git a/trunk/drivers/media/video/uvc/Makefile b/trunk/drivers/media/video/uvc/Makefile deleted file mode 100644 index 968c1994eda0..000000000000 --- a/trunk/drivers/media/video/uvc/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \ - uvc_status.o uvc_isight.o -obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o diff --git a/trunk/drivers/media/video/uvc/uvc_ctrl.c b/trunk/drivers/media/video/uvc/uvc_ctrl.c deleted file mode 100644 index f0ee46d15540..000000000000 --- a/trunk/drivers/media/video/uvc/uvc_ctrl.c +++ /dev/null @@ -1,1256 +0,0 @@ -/* - * uvc_ctrl.c -- USB Video Class driver - Controls - * - * Copyright (C) 2005-2008 - * Laurent Pinchart (laurent.pinchart@skynet.be) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "uvcvideo.h" - -#define UVC_CTRL_NDATA 2 -#define UVC_CTRL_DATA_CURRENT 0 -#define UVC_CTRL_DATA_BACKUP 1 - -/* ------------------------------------------------------------------------ - * Control, formats, ... - */ - -static struct uvc_control_info uvc_ctrls[] = { - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BRIGHTNESS_CONTROL, - .index = 0, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_CONTRAST_CONTROL, - .index = 1, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_CONTROL, - .index = 2, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SATURATION_CONTROL, - .index = 3, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SHARPNESS_CONTROL, - .index = 4, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAMMA_CONTROL, - .index = 5, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BACKLIGHT_COMPENSATION_CONTROL, - .index = 8, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAIN_CONTROL, - .index = 9, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_POWER_LINE_FREQUENCY_CONTROL, - .index = 10, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_AUTO_CONTROL, - .index = 11, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_MODE_CONTROL, - .index = 1, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_PRIORITY_CONTROL, - .index = 2, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, - .index = 3, - .size = 4, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_ABSOLUTE_CONTROL, - .index = 5, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_AUTO_CONTROL, - .index = 17, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, - .index = 12, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, - .index = 6, - .size = 2, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, - .index = 13, - .size = 1, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR - | UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE, - }, - { - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, - .index = 7, - .size = 4, - .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE - | UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE, - }, -}; - -static struct uvc_menu_info power_line_frequency_controls[] = { - { 0, "Disabled" }, - { 1, "50 Hz" }, - { 2, "60 Hz" }, -}; - -static struct uvc_menu_info exposure_auto_controls[] = { - { 1, "Manual Mode" }, - { 2, "Auto Mode" }, - { 4, "Shutter Priority Mode" }, - { 8, "Aperture Priority Mode" }, -}; - -static struct uvc_control_mapping uvc_ctrl_mappings[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BRIGHTNESS_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_SIGNED, - }, - { - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_CONTRAST_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_HUE, - .name = "Hue", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_SIGNED, - }, - { - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SATURATION_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_SHARPNESS, - .name = "Sharpness", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SHARPNESS_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_GAMMA, - .name = "Gamma", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAMMA_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_BACKLIGHT_COMPENSATION, - .name = "Backlight Compensation", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BACKLIGHT_COMPENSATION_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_GAIN, - .name = "Gain", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAIN_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .name = "Power Line Frequency", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_POWER_LINE_FREQUENCY_CONTROL, - .size = 2, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_MENU, - .data_type = UVC_CTRL_DATA_TYPE_ENUM, - .menu_info = power_line_frequency_controls, - .menu_count = ARRAY_SIZE(power_line_frequency_controls), - }, - { - .id = V4L2_CID_HUE_AUTO, - .name = "Hue, Auto", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_AUTO_CONTROL, - .size = 1, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, - .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, - }, - { - .id = V4L2_CID_EXPOSURE_AUTO, - .name = "Exposure, Auto", - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_MODE_CONTROL, - .size = 4, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_MENU, - .data_type = UVC_CTRL_DATA_TYPE_BITMASK, - .menu_info = exposure_auto_controls, - .menu_count = ARRAY_SIZE(exposure_auto_controls), - }, - { - .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY, - .name = "Exposure, Auto Priority", - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_PRIORITY_CONTROL, - .size = 1, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, - .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, - }, - { - .id = V4L2_CID_EXPOSURE_ABSOLUTE, - .name = "Exposure (Absolute)", - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, - .size = 32, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .name = "White Balance Temperature, Auto", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, - .size = 1, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, - .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, - }, - { - .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, - .name = "White Balance Temperature", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .name = "White Balance Component, Auto", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, - .size = 1, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, - .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, - }, - { - .id = V4L2_CID_BLUE_BALANCE, - .name = "White Balance Blue Component", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_SIGNED, - }, - { - .id = V4L2_CID_RED_BALANCE, - .name = "White Balance Red Component", - .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, - .size = 16, - .offset = 16, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_SIGNED, - }, - { - .id = V4L2_CID_FOCUS_ABSOLUTE, - .name = "Focus (absolute)", - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_ABSOLUTE_CONTROL, - .size = 16, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, - }, - { - .id = V4L2_CID_FOCUS_AUTO, - .name = "Focus, Auto", - .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_AUTO_CONTROL, - .size = 1, - .offset = 0, - .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, - .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN, - }, -}; - -/* ------------------------------------------------------------------------ - * Utility functions - */ - -static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) -{ - return ctrl->data + id * ctrl->info->size; -} - -static inline int uvc_get_bit(const __u8 *data, int bit) -{ - return (data[bit >> 3] >> (bit & 7)) & 1; -} - -/* Extract the bit string specified by mapping->offset and mapping->size - * from the little-endian data stored at 'data' and return the result as - * a signed 32bit integer. Sign extension will be performed if the mapping - * references a signed data type. - */ -static __s32 uvc_get_le_value(const __u8 *data, - struct uvc_control_mapping *mapping) -{ - int bits = mapping->size; - int offset = mapping->offset; - __s32 value = 0; - __u8 mask; - - data += offset / 8; - offset &= 7; - mask = ((1LL << bits) - 1) << offset; - - for (; bits > 0; data++) { - __u8 byte = *data & mask; - value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); - bits -= 8 - (offset > 0 ? offset : 0); - offset -= 8; - mask = (1 << bits) - 1; - } - - /* Sign-extend the value if needed */ - if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) - value |= -(value & (1 << (mapping->size - 1))); - - return value; -} - -/* Set the bit string specified by mapping->offset and mapping->size - * in the little-endian data stored at 'data' to the value 'value'. - */ -static void uvc_set_le_value(__s32 value, __u8 *data, - struct uvc_control_mapping *mapping) -{ - int bits = mapping->size; - int offset = mapping->offset; - __u8 mask; - - data += offset / 8; - offset &= 7; - - for (; bits > 0; data++) { - mask = ((1LL << bits) - 1) << offset; - *data = (*data & ~mask) | ((value << offset) & mask); - value >>= offset ? offset : 8; - bits -= 8 - offset; - offset = 0; - } -} - -/* ------------------------------------------------------------------------ - * Terminal and unit management - */ - -static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; -static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; -static const __u8 uvc_media_transport_input_guid[16] = - UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; - -static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16]) -{ - switch (UVC_ENTITY_TYPE(entity)) { - case ITT_CAMERA: - return memcmp(uvc_camera_guid, guid, 16) == 0; - - case ITT_MEDIA_TRANSPORT_INPUT: - return memcmp(uvc_media_transport_input_guid, guid, 16) == 0; - - case VC_PROCESSING_UNIT: - return memcmp(uvc_processing_guid, guid, 16) == 0; - - case VC_EXTENSION_UNIT: - return memcmp(entity->extension.guidExtensionCode, - guid, 16) == 0; - - default: - return 0; - } -} - -/* ------------------------------------------------------------------------ - * UVC Controls - */ - -static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, - struct uvc_control_mapping **mapping, struct uvc_control **control, - int next) -{ - struct uvc_control *ctrl; - struct uvc_control_mapping *map; - unsigned int i; - - if (entity == NULL) - return; - - for (i = 0; i < entity->ncontrols; ++i) { - ctrl = &entity->controls[i]; - if (ctrl->info == NULL) - continue; - - list_for_each_entry(map, &ctrl->info->mappings, list) { - if ((map->id == v4l2_id) && !next) { - *control = ctrl; - *mapping = map; - return; - } - - if ((*mapping == NULL || (*mapping)->id > map->id) && - (map->id > v4l2_id) && next) { - *control = ctrl; - *mapping = map; - } - } - } -} - -struct uvc_control *uvc_find_control(struct uvc_video_device *video, - __u32 v4l2_id, struct uvc_control_mapping **mapping) -{ - struct uvc_control *ctrl = NULL; - struct uvc_entity *entity; - int next = v4l2_id & V4L2_CTRL_FLAG_NEXT_CTRL; - - *mapping = NULL; - - /* Mask the query flags. */ - v4l2_id &= V4L2_CTRL_ID_MASK; - - /* Find the control. */ - __uvc_find_control(video->processing, v4l2_id, mapping, &ctrl, next); - if (ctrl && !next) - return ctrl; - - list_for_each_entry(entity, &video->iterms, chain) { - __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); - if (ctrl && !next) - return ctrl; - } - - list_for_each_entry(entity, &video->extensions, chain) { - __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); - if (ctrl && !next) - return ctrl; - } - - if (ctrl == NULL && !next) - uvc_trace(UVC_TRACE_CONTROL, "Control 0x%08x not found.\n", - v4l2_id); - - return ctrl; -} - -int uvc_query_v4l2_ctrl(struct uvc_video_device *video, - struct v4l2_queryctrl *v4l2_ctrl) -{ - struct uvc_control *ctrl; - struct uvc_control_mapping *mapping; - struct uvc_menu_info *menu; - unsigned int i; - __u8 data[8]; - int ret; - - ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); - if (ctrl == NULL) - return -EINVAL; - - v4l2_ctrl->id = mapping->id; - v4l2_ctrl->type = mapping->v4l2_type; - strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); - v4l2_ctrl->flags = 0; - - if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) - v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; - - if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { - if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; - v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); - } - - if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { - v4l2_ctrl->minimum = 0; - v4l2_ctrl->maximum = mapping->menu_count - 1; - v4l2_ctrl->step = 1; - - menu = mapping->menu_info; - for (i = 0; i < mapping->menu_count; ++i, ++menu) { - if (menu->value == v4l2_ctrl->default_value) { - v4l2_ctrl->default_value = i; - break; - } - } - - return 0; - } - - if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { - if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; - v4l2_ctrl->minimum = uvc_get_le_value(data, mapping); - } - if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { - if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; - v4l2_ctrl->maximum = uvc_get_le_value(data, mapping); - } - if (ctrl->info->flags & UVC_CONTROL_GET_RES) { - if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - &data, ctrl->info->size)) < 0) - return ret; - v4l2_ctrl->step = uvc_get_le_value(data, mapping); - } - - return 0; -} - - -/* -------------------------------------------------------------------------- - * Control transactions - * - * To make extended set operations as atomic as the hardware allows, controls - * are handled using begin/commit/rollback operations. - * - * At the beginning of a set request, uvc_ctrl_begin should be called to - * initialize the request. This function acquires the control lock. - * - * When setting a control, the new value is stored in the control data field - * at position UVC_CTRL_DATA_CURRENT. The control is then marked as dirty for - * later processing. If the UVC and V4L2 control sizes differ, the current - * value is loaded from the hardware before storing the new value in the data - * field. - * - * After processing all controls in the transaction, uvc_ctrl_commit or - * uvc_ctrl_rollback must be called to apply the pending changes to the - * hardware or revert them. When applying changes, all controls marked as - * dirty will be modified in the UVC device, and the dirty flag will be - * cleared. When reverting controls, the control data field - * UVC_CTRL_DATA_CURRENT is reverted to its previous value - * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the - * control lock. - */ -int uvc_ctrl_begin(struct uvc_video_device *video) -{ - return mutex_lock_interruptible(&video->ctrl_mutex) ? -ERESTARTSYS : 0; -} - -static int uvc_ctrl_commit_entity(struct uvc_device *dev, - struct uvc_entity *entity, int rollback) -{ - struct uvc_control *ctrl; - unsigned int i; - int ret; - - if (entity == NULL) - return 0; - - for (i = 0; i < entity->ncontrols; ++i) { - ctrl = &entity->controls[i]; - if (ctrl->info == NULL || !ctrl->dirty) - continue; - - if (!rollback) - ret = uvc_query_ctrl(dev, SET_CUR, ctrl->entity->id, - dev->intfnum, ctrl->info->selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info->size); - else - ret = 0; - - if (rollback || ret < 0) - memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), - ctrl->info->size); - - if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) - ctrl->loaded = 0; - - ctrl->dirty = 0; - - if (ret < 0) - return ret; - } - - return 0; -} - -int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback) -{ - struct uvc_entity *entity; - int ret = 0; - - /* Find the control. */ - ret = uvc_ctrl_commit_entity(video->dev, video->processing, rollback); - if (ret < 0) - goto done; - - list_for_each_entry(entity, &video->iterms, chain) { - ret = uvc_ctrl_commit_entity(video->dev, entity, rollback); - if (ret < 0) - goto done; - } - - list_for_each_entry(entity, &video->extensions, chain) { - ret = uvc_ctrl_commit_entity(video->dev, entity, rollback); - if (ret < 0) - goto done; - } - -done: - mutex_unlock(&video->ctrl_mutex); - return ret; -} - -int uvc_ctrl_get(struct uvc_video_device *video, - struct v4l2_ext_control *xctrl) -{ - struct uvc_control *ctrl; - struct uvc_control_mapping *mapping; - struct uvc_menu_info *menu; - unsigned int i; - int ret; - - ctrl = uvc_find_control(video, xctrl->id, &mapping); - if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) - return -EINVAL; - - if (!ctrl->loaded) { - ret = uvc_query_ctrl(video->dev, GET_CUR, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info->size); - if (ret < 0) - return ret; - - if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0) - ctrl->loaded = 1; - } - - xctrl->value = uvc_get_le_value( - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), mapping); - - if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { - menu = mapping->menu_info; - for (i = 0; i < mapping->menu_count; ++i, ++menu) { - if (menu->value == xctrl->value) { - xctrl->value = i; - break; - } - } - } - - return 0; -} - -int uvc_ctrl_set(struct uvc_video_device *video, - struct v4l2_ext_control *xctrl) -{ - struct uvc_control *ctrl; - struct uvc_control_mapping *mapping; - s32 value = xctrl->value; - int ret; - - ctrl = uvc_find_control(video, xctrl->id, &mapping); - if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) - return -EINVAL; - - if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { - if (value < 0 || value >= mapping->menu_count) - return -EINVAL; - value = mapping->menu_info[value].value; - } - - if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { - if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { - memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - 0, ctrl->info->size); - } else { - ret = uvc_query_ctrl(video->dev, GET_CUR, - ctrl->entity->id, video->dev->intfnum, - ctrl->info->selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info->size); - if (ret < 0) - return ret; - } - - if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0) - ctrl->loaded = 1; - } - - if (!ctrl->dirty) { - memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info->size); - } - - uvc_set_le_value(value, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), mapping); - - ctrl->dirty = 1; - ctrl->modified = 1; - return 0; -} - -/* -------------------------------------------------------------------------- - * Dynamic controls - */ - -int uvc_xu_ctrl_query(struct uvc_video_device *video, - struct uvc_xu_control *xctrl, int set) -{ - struct uvc_entity *entity; - struct uvc_control *ctrl = NULL; - unsigned int i, found = 0; - __u8 *data; - int ret; - - /* Find the extension unit. */ - list_for_each_entry(entity, &video->extensions, chain) { - if (entity->id == xctrl->unit) - break; - } - - if (entity->id != xctrl->unit) { - uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n", - xctrl->unit); - return -EINVAL; - } - - /* Find the control. */ - for (i = 0; i < entity->ncontrols; ++i) { - ctrl = &entity->controls[i]; - if (ctrl->info == NULL) - continue; - - if (ctrl->info->selector == xctrl->selector) { - found = 1; - break; - } - } - - if (!found) { - uvc_trace(UVC_TRACE_CONTROL, - "Control " UVC_GUID_FORMAT "/%u not found.\n", - UVC_GUID_ARGS(entity->extension.guidExtensionCode), - xctrl->selector); - return -EINVAL; - } - - /* Validate control data size. */ - if (ctrl->info->size != xctrl->size) - return -EINVAL; - - if ((set && !(ctrl->info->flags & UVC_CONTROL_SET_CUR)) || - (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR))) - return -EINVAL; - - if (mutex_lock_interruptible(&video->ctrl_mutex)) - return -ERESTARTSYS; - - memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - xctrl->size); - data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); - - if (set && copy_from_user(data, xctrl->data, xctrl->size)) { - ret = -EFAULT; - goto out; - } - - ret = uvc_query_ctrl(video->dev, set ? SET_CUR : GET_CUR, xctrl->unit, - video->dev->intfnum, xctrl->selector, data, - xctrl->size); - if (ret < 0) - goto out; - - if (!set && copy_to_user(xctrl->data, data, xctrl->size)) { - ret = -EFAULT; - goto out; - } - -out: - if (ret) - memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), - xctrl->size); - - mutex_unlock(&video->ctrl_mutex); - return ret; -} - -/* -------------------------------------------------------------------------- - * Suspend/resume - */ - -/* - * Restore control values after resume, skipping controls that haven't been - * changed. - * - * TODO - * - Don't restore modified controls that are back to their default value. - * - Handle restore order (Auto-Exposure Mode should be restored before - * Exposure Time). - */ -int uvc_ctrl_resume_device(struct uvc_device *dev) -{ - struct uvc_control *ctrl; - struct uvc_entity *entity; - unsigned int i; - int ret; - - /* Walk the entities list and restore controls when possible. */ - list_for_each_entry(entity, &dev->entities, list) { - - for (i = 0; i < entity->ncontrols; ++i) { - ctrl = &entity->controls[i]; - - if (ctrl->info == NULL || !ctrl->modified || - (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) - continue; - - printk(KERN_INFO "restoring control " UVC_GUID_FORMAT - "/%u/%u\n", UVC_GUID_ARGS(ctrl->info->entity), - ctrl->info->index, ctrl->info->selector); - ctrl->dirty = 1; - } - - ret = uvc_ctrl_commit_entity(dev, entity, 0); - if (ret < 0) - return ret; - } - - return 0; -} - -/* -------------------------------------------------------------------------- - * Control and mapping handling - */ - -static void uvc_ctrl_add_ctrl(struct uvc_device *dev, - struct uvc_control_info *info) -{ - struct uvc_entity *entity; - struct uvc_control *ctrl = NULL; - int ret, found = 0; - unsigned int i; - - list_for_each_entry(entity, &dev->entities, list) { - if (!uvc_entity_match_guid(entity, info->entity)) - continue; - - for (i = 0; i < entity->ncontrols; ++i) { - ctrl = &entity->controls[i]; - if (ctrl->index == info->index) { - found = 1; - break; - } - } - - if (found) - break; - } - - if (!found) - return; - - if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) { - /* Check if the device control information and length match - * the user supplied information. - */ - __u32 flags; - __le16 size; - __u8 inf; - - if ((ret = uvc_query_ctrl(dev, GET_LEN, ctrl->entity->id, - dev->intfnum, info->selector, (__u8 *)&size, 2)) < 0) { - uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on " - "control " UVC_GUID_FORMAT "/%u (%d).\n", - UVC_GUID_ARGS(info->entity), info->selector, - ret); - return; - } - - if (info->size != le16_to_cpu(size)) { - uvc_trace(UVC_TRACE_CONTROL, "Control " UVC_GUID_FORMAT - "/%u size doesn't match user supplied " - "value.\n", UVC_GUID_ARGS(info->entity), - info->selector); - return; - } - - if ((ret = uvc_query_ctrl(dev, GET_INFO, ctrl->entity->id, - dev->intfnum, info->selector, &inf, 1)) < 0) { - uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on " - "control " UVC_GUID_FORMAT "/%u (%d).\n", - UVC_GUID_ARGS(info->entity), info->selector, - ret); - return; - } - - flags = info->flags; - if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) || - ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) { - uvc_trace(UVC_TRACE_CONTROL, "Control " - UVC_GUID_FORMAT "/%u flags don't match " - "supported operations.\n", - UVC_GUID_ARGS(info->entity), info->selector); - return; - } - } - - ctrl->info = info; - ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_NDATA, GFP_KERNEL); - uvc_trace(UVC_TRACE_CONTROL, "Added control " UVC_GUID_FORMAT "/%u " - "to device %s entity %u\n", UVC_GUID_ARGS(ctrl->info->entity), - ctrl->info->selector, dev->udev->devpath, entity->id); -} - -/* - * Add an item to the UVC control information list, and instantiate a control - * structure for each device that supports the control. - */ -int uvc_ctrl_add_info(struct uvc_control_info *info) -{ - struct uvc_control_info *ctrl; - struct uvc_device *dev; - int ret = 0; - - /* Find matching controls by walking the devices, entities and - * controls list. - */ - mutex_lock(&uvc_driver.ctrl_mutex); - - /* First check if the list contains a control matching the new one. - * Bail out if it does. - */ - list_for_each_entry(ctrl, &uvc_driver.controls, list) { - if (memcmp(ctrl->entity, info->entity, 16)) - continue; - - if (ctrl->selector == info->selector) { - uvc_trace(UVC_TRACE_CONTROL, "Control " - UVC_GUID_FORMAT "/%u is already defined.\n", - UVC_GUID_ARGS(info->entity), info->selector); - ret = -EEXIST; - goto end; - } - if (ctrl->index == info->index) { - uvc_trace(UVC_TRACE_CONTROL, "Control " - UVC_GUID_FORMAT "/%u would overwrite index " - "%d.\n", UVC_GUID_ARGS(info->entity), - info->selector, info->index); - ret = -EEXIST; - goto end; - } - } - - list_for_each_entry(dev, &uvc_driver.devices, list) - uvc_ctrl_add_ctrl(dev, info); - - INIT_LIST_HEAD(&info->mappings); - list_add_tail(&info->list, &uvc_driver.controls); -end: - mutex_unlock(&uvc_driver.ctrl_mutex); - return ret; -} - -int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping) -{ - struct uvc_control_info *info; - struct uvc_control_mapping *map; - int ret = -EINVAL; - - if (mapping->id & ~V4L2_CTRL_ID_MASK) { - uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s' with " - "invalid control id 0x%08x\n", mapping->name, - mapping->id); - return -EINVAL; - } - - mutex_lock(&uvc_driver.ctrl_mutex); - list_for_each_entry(info, &uvc_driver.controls, list) { - if (memcmp(info->entity, mapping->entity, 16) || - info->selector != mapping->selector) - continue; - - if (info->size * 8 < mapping->size + mapping->offset) { - uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' would " - "overflow control " UVC_GUID_FORMAT "/%u\n", - mapping->name, UVC_GUID_ARGS(info->entity), - info->selector); - ret = -EOVERFLOW; - goto end; - } - - /* Check if the list contains a mapping matching the new one. - * Bail out if it does. - */ - list_for_each_entry(map, &info->mappings, list) { - if (map->id == mapping->id) { - uvc_trace(UVC_TRACE_CONTROL, "Mapping '%s' is " - "already defined.\n", mapping->name); - ret = -EEXIST; - goto end; - } - } - - mapping->ctrl = info; - list_add_tail(&mapping->list, &info->mappings); - uvc_trace(UVC_TRACE_CONTROL, "Adding mapping %s to control " - UVC_GUID_FORMAT "/%u.\n", mapping->name, - UVC_GUID_ARGS(info->entity), info->selector); - - ret = 0; - break; - } -end: - mutex_unlock(&uvc_driver.ctrl_mutex); - return ret; -} - -/* - * Initialize device controls. - */ -int uvc_ctrl_init_device(struct uvc_device *dev) -{ - struct uvc_control_info *info; - struct uvc_control *ctrl; - struct uvc_entity *entity; - unsigned int i; - - /* Walk the entities list and instantiate controls */ - list_for_each_entry(entity, &dev->entities, list) { - unsigned int bControlSize = 0, ncontrols = 0; - __u8 *bmControls = NULL; - - if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) { - bmControls = entity->extension.bmControls; - bControlSize = entity->extension.bControlSize; - } else if (UVC_ENTITY_TYPE(entity) == VC_PROCESSING_UNIT) { - bmControls = entity->processing.bmControls; - bControlSize = entity->processing.bControlSize; - } else if (UVC_ENTITY_TYPE(entity) == ITT_CAMERA) { - bmControls = entity->camera.bmControls; - bControlSize = entity->camera.bControlSize; - } - - for (i = 0; i < bControlSize; ++i) - ncontrols += hweight8(bmControls[i]); - - if (ncontrols == 0) - continue; - - entity->controls = kzalloc(ncontrols*sizeof *ctrl, GFP_KERNEL); - if (entity->controls == NULL) - return -ENOMEM; - - entity->ncontrols = ncontrols; - - ctrl = entity->controls; - for (i = 0; i < bControlSize * 8; ++i) { - if (uvc_get_bit(bmControls, i) == 0) - continue; - - ctrl->entity = entity; - ctrl->index = i; - ctrl++; - } - } - - /* Walk the controls info list and associate them with the device - * controls, then add the device to the global device list. This has - * to be done while holding the controls lock, to make sure - * uvc_ctrl_add_info() will not get called in-between. - */ - mutex_lock(&uvc_driver.ctrl_mutex); - list_for_each_entry(info, &uvc_driver.controls, list) - uvc_ctrl_add_ctrl(dev, info); - - list_add_tail(&dev->list, &uvc_driver.devices); - mutex_unlock(&uvc_driver.ctrl_mutex); - - return 0; -} - -/* - * Cleanup device controls. - */ -void uvc_ctrl_cleanup_device(struct uvc_device *dev) -{ - struct uvc_entity *entity; - unsigned int i; - - /* Remove the device from the global devices list */ - mutex_lock(&uvc_driver.ctrl_mutex); - if (dev->list.next != NULL) - list_del(&dev->list); - mutex_unlock(&uvc_driver.ctrl_mutex); - - list_for_each_entry(entity, &dev->entities, list) { - for (i = 0; i < entity->ncontrols; ++i) - kfree(entity->controls[i].data); - - kfree(entity->controls); - } -} - -void uvc_ctrl_init(void) -{ - struct uvc_control_info *ctrl = uvc_ctrls; - struct uvc_control_info *cend = ctrl + ARRAY_SIZE(uvc_ctrls); - struct uvc_control_mapping *mapping = uvc_ctrl_mappings; - struct uvc_control_mapping *mend = - mapping + ARRAY_SIZE(uvc_ctrl_mappings); - - for (; ctrl < cend; ++ctrl) - uvc_ctrl_add_info(ctrl); - - for (; mapping < mend; ++mapping) - uvc_ctrl_add_mapping(mapping); -} diff --git a/trunk/drivers/media/video/uvc/uvc_driver.c b/trunk/drivers/media/video/uvc/uvc_driver.c deleted file mode 100644 index 60ced589f898..000000000000 --- a/trunk/drivers/media/video/uvc/uvc_driver.c +++ /dev/null @@ -1,1955 +0,0 @@ -/* - * uvc_driver.c -- USB Video Class driver - * - * Copyright (C) 2005-2008 - * Laurent Pinchart (laurent.pinchart@skynet.be) - * - * 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 driver aims to support video input devices compliant with the 'USB - * Video Class' specification. - * - * The driver doesn't support the deprecated v4l1 interface. It implements the - * mmap capture method only, and doesn't do any image format conversion in - * software. If your user-space application doesn't support YUYV or MJPEG, fix - * it :-). Please note that the MJPEG data have been stripped from their - * Huffman tables (DHT marker), you will need to add it back if your JPEG - * codec can't handle MJPEG data. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "uvcvideo.h" - -#define DRIVER_AUTHOR "Laurent Pinchart " -#define DRIVER_DESC "USB Video Class driver" -#ifndef DRIVER_VERSION -#define DRIVER_VERSION "v0.1.0" -#endif - -static unsigned int uvc_quirks_param; -unsigned int uvc_trace_param; - -/* ------------------------------------------------------------------------ - * Control, formats, ... - */ - -static struct uvc_format_desc uvc_fmts[] = { - { - .name = "YUV 4:2:2 (YUYV)", - .guid = UVC_GUID_FORMAT_YUY2, - .fcc = V4L2_PIX_FMT_YUYV, - }, - { - .name = "YUV 4:2:0 (NV12)", - .guid = UVC_GUID_FORMAT_NV12, - .fcc = V4L2_PIX_FMT_NV12, - }, - { - .name = "MJPEG", - .guid = UVC_GUID_FORMAT_MJPEG, - .fcc = V4L2_PIX_FMT_MJPEG, - }, - { - .name = "YVU 4:2:0 (YV12)", - .guid = UVC_GUID_FORMAT_YV12, - .fcc = V4L2_PIX_FMT_YVU420, - }, - { - .name = "YUV 4:2:0 (I420)", - .guid = UVC_GUID_FORMAT_I420, - .fcc = V4L2_PIX_FMT_YUV420, - }, - { - .name = "YUV 4:2:2 (UYVY)", - .guid = UVC_GUID_FORMAT_UYVY, - .fcc = V4L2_PIX_FMT_UYVY, - }, - { - .name = "Greyscale", - .guid = UVC_GUID_FORMAT_Y800, - .fcc = V4L2_PIX_FMT_GREY, - }, - { - .name = "RGB Bayer", - .guid = UVC_GUID_FORMAT_BY8, - .fcc = V4L2_PIX_FMT_SBGGR8, - }, -}; - -/* ------------------------------------------------------------------------ - * Utility functions - */ - -struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, - __u8 epaddr) -{ - struct usb_host_endpoint *ep; - unsigned int i; - - for (i = 0; i < alts->desc.bNumEndpoints; ++i) { - ep = &alts->endpoint[i]; - if (ep->desc.bEndpointAddress == epaddr) - return ep; - } - - return NULL; -} - -static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16]) -{ - unsigned int len = ARRAY_SIZE(uvc_fmts); - unsigned int i; - - for (i = 0; i < len; ++i) { - if (memcmp(guid, uvc_fmts[i].guid, 16) == 0) - return &uvc_fmts[i]; - } - - return NULL; -} - -static __u32 uvc_colorspace(const __u8 primaries) -{ - static const __u8 colorprimaries[] = { - 0, - V4L2_COLORSPACE_SRGB, - V4L2_COLORSPACE_470_SYSTEM_M, - V4L2_COLORSPACE_470_SYSTEM_BG, - V4L2_COLORSPACE_SMPTE170M, - V4L2_COLORSPACE_SMPTE240M, - }; - - if (primaries < ARRAY_SIZE(colorprimaries)) - return colorprimaries[primaries]; - - return 0; -} - -/* Simplify a fraction using a simple continued fraction decomposition. The - * idea here is to convert fractions such as 333333/10000000 to 1/30 using - * 32 bit arithmetic only. The algorithm is not perfect and relies upon two - * arbitrary parameters to remove non-significative terms from the simple - * continued fraction decomposition. Using 8 and 333 for n_terms and threshold - * respectively seems to give nice results. - */ -void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, - unsigned int n_terms, unsigned int threshold) -{ - uint32_t *an; - uint32_t x, y, r; - unsigned int i, n; - - an = kmalloc(n_terms * sizeof *an, GFP_KERNEL); - if (an == NULL) - return; - - /* Convert the fraction to a simple continued fraction. See - * http://mathforum.org/dr.math/faq/faq.fractions.html - * Stop if the current term is bigger than or equal to the given - * threshold. - */ - x = *numerator; - y = *denominator; - - for (n = 0; n < n_terms && y != 0; ++n) { - an[n] = x / y; - if (an[n] >= threshold) { - if (n < 2) - n++; - break; - } - - r = x - an[n] * y; - x = y; - y = r; - } - - /* Expand the simple continued fraction back to an integer fraction. */ - x = 0; - y = 1; - - for (i = n; i > 0; --i) { - r = y; - y = an[i-1] * y + x; - x = r; - } - - *numerator = y; - *denominator = x; - kfree(an); -} - -/* Convert a fraction to a frame interval in 100ns multiples. The idea here is - * to compute numerator / denominator * 10000000 using 32 bit fixed point - * arithmetic only. - */ -uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator) -{ - uint32_t multiplier; - - /* Saturate the result if the operation would overflow. */ - if (denominator == 0 || - numerator/denominator >= ((uint32_t)-1)/10000000) - return (uint32_t)-1; - - /* Divide both the denominator and the multiplier by two until - * numerator * multiplier doesn't overflow. If anyone knows a better - * algorithm please let me know. - */ - multiplier = 10000000; - while (numerator > ((uint32_t)-1)/multiplier) { - multiplier /= 2; - denominator /= 2; - } - - return denominator ? numerator * multiplier / denominator : 0; -} - -/* ------------------------------------------------------------------------ - * Terminal and unit management - */ - -static struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id) -{ - struct uvc_entity *entity; - - list_for_each_entry(entity, &dev->entities, list) { - if (entity->id == id) - return entity; - } - - return NULL; -} - -static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev, - int id, struct uvc_entity *entity) -{ - unsigned int i; - - if (entity == NULL) - entity = list_entry(&dev->entities, struct uvc_entity, list); - - list_for_each_entry_continue(entity, &dev->entities, list) { - switch (UVC_ENTITY_TYPE(entity)) { - case TT_STREAMING: - if (entity->output.bSourceID == id) - return entity; - break; - - case VC_PROCESSING_UNIT: - if (entity->processing.bSourceID == id) - return entity; - break; - - case VC_SELECTOR_UNIT: - for (i = 0; i < entity->selector.bNrInPins; ++i) - if (entity->selector.baSourceID[i] == id) - return entity; - break; - - case VC_EXTENSION_UNIT: - for (i = 0; i < entity->extension.bNrInPins; ++i) - if (entity->extension.baSourceID[i] == id) - return entity; - break; - } - } - - return NULL; -} - -/* ------------------------------------------------------------------------ - * Descriptors handling - */ - -static int uvc_parse_format(struct uvc_device *dev, - struct uvc_streaming *streaming, struct uvc_format *format, - __u32 **intervals, unsigned char *buffer, int buflen) -{ - struct usb_interface *intf = streaming->intf; - struct usb_host_interface *alts = intf->cur_altsetting; - struct uvc_format_desc *fmtdesc; - struct uvc_frame *frame; - const unsigned char *start = buffer; - unsigned int interval; - unsigned int i, n; - __u8 ftype; - - format->type = buffer[2]; - format->index = buffer[3]; - - switch (buffer[2]) { - case VS_FORMAT_UNCOMPRESSED: - case VS_FORMAT_FRAME_BASED: - if (buflen < 27) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d FORMAT error\n", - dev->udev->devnum, - alts->desc.bInterfaceNumber); - return -EINVAL; - } - - /* Find the format descriptor from its GUID. */ - fmtdesc = uvc_format_by_guid(&buffer[5]); - - if (fmtdesc != NULL) { - strncpy(format->name, fmtdesc->name, - sizeof format->name); - format->fcc = fmtdesc->fcc; - } else { - uvc_printk(KERN_INFO, "Unknown video format " - UVC_GUID_FORMAT "\n", - UVC_GUID_ARGS(&buffer[5])); - snprintf(format->name, sizeof format->name, - UVC_GUID_FORMAT, UVC_GUID_ARGS(&buffer[5])); - format->fcc = 0; - } - - format->bpp = buffer[21]; - if (buffer[2] == VS_FORMAT_UNCOMPRESSED) { - ftype = VS_FRAME_UNCOMPRESSED; - } else { - ftype = VS_FRAME_FRAME_BASED; - if (buffer[27]) - format->flags = UVC_FMT_FLAG_COMPRESSED; - } - break; - - case VS_FORMAT_MJPEG: - if (buflen < 11) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d FORMAT error\n", - dev->udev->devnum, - alts->desc.bInterfaceNumber); - return -EINVAL; - } - - strncpy(format->name, "MJPEG", sizeof format->name); - format->fcc = V4L2_PIX_FMT_MJPEG; - format->flags = UVC_FMT_FLAG_COMPRESSED; - format->bpp = 0; - ftype = VS_FRAME_MJPEG; - break; - - case VS_FORMAT_DV: - if (buflen < 9) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d FORMAT error\n", - dev->udev->devnum, - alts->desc.bInterfaceNumber); - return -EINVAL; - } - - switch (buffer[8] & 0x7f) { - case 0: - strncpy(format->name, "SD-DV", sizeof format->name); - break; - case 1: - strncpy(format->name, "SDL-DV", sizeof format->name); - break; - case 2: - strncpy(format->name, "HD-DV", sizeof format->name); - break; - default: - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d: unknown DV format %u\n", - dev->udev->devnum, - alts->desc.bInterfaceNumber, buffer[8]); - return -EINVAL; - } - - strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", - sizeof format->name); - - format->fcc = V4L2_PIX_FMT_DV; - format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; - format->bpp = 0; - ftype = 0; - - /* Create a dummy frame descriptor. */ - frame = &format->frame[0]; - memset(&format->frame[0], 0, sizeof format->frame[0]); - frame->bFrameIntervalType = 1; - frame->dwDefaultFrameInterval = 1; - frame->dwFrameInterval = *intervals; - *(*intervals)++ = 1; - format->nframes = 1; - break; - - case VS_FORMAT_MPEG2TS: - case VS_FORMAT_STREAM_BASED: - /* Not supported yet. */ - default: - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d unsupported format %u\n", - dev->udev->devnum, alts->desc.bInterfaceNumber, - buffer[2]); - return -EINVAL; - } - - uvc_trace(UVC_TRACE_DESCR, "Found format %s.\n", format->name); - - buflen -= buffer[0]; - buffer += buffer[0]; - - /* Parse the frame descriptors. Only uncompressed, MJPEG and frame - * based formats have frame descriptors. - */ - while (buflen > 2 && buffer[2] == ftype) { - frame = &format->frame[format->nframes]; - - if (ftype != VS_FRAME_FRAME_BASED) - n = buflen > 25 ? buffer[25] : 0; - else - n = buflen > 21 ? buffer[21] : 0; - - n = n ? n : 3; - - if (buflen < 26 + 4*n) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d FRAME error\n", dev->udev->devnum, - alts->desc.bInterfaceNumber); - return -EINVAL; - } - - frame->bFrameIndex = buffer[3]; - frame->bmCapabilities = buffer[4]; - frame->wWidth = le16_to_cpup((__le16 *)&buffer[5]); - frame->wHeight = le16_to_cpup((__le16 *)&buffer[7]); - frame->dwMinBitRate = le32_to_cpup((__le32 *)&buffer[9]); - frame->dwMaxBitRate = le32_to_cpup((__le32 *)&buffer[13]); - if (ftype != VS_FRAME_FRAME_BASED) { - frame->dwMaxVideoFrameBufferSize = - le32_to_cpup((__le32 *)&buffer[17]); - frame->dwDefaultFrameInterval = - le32_to_cpup((__le32 *)&buffer[21]); - frame->bFrameIntervalType = buffer[25]; - } else { - frame->dwMaxVideoFrameBufferSize = 0; - frame->dwDefaultFrameInterval = - le32_to_cpup((__le32 *)&buffer[17]); - frame->bFrameIntervalType = buffer[21]; - } - frame->dwFrameInterval = *intervals; - - /* Several UVC chipsets screw up dwMaxVideoFrameBufferSize - * completely. Observed behaviours range from setting the - * value to 1.1x the actual frame size of hardwiring the - * 16 low bits to 0. This results in a higher than necessary - * memory usage as well as a wrong image size information. For - * uncompressed formats this can be fixed by computing the - * value from the frame size. - */ - if (!(format->flags & UVC_FMT_FLAG_COMPRESSED)) - frame->dwMaxVideoFrameBufferSize = format->bpp - * frame->wWidth * frame->wHeight / 8; - - /* Some bogus devices report dwMinFrameInterval equal to - * dwMaxFrameInterval and have dwFrameIntervalStep set to - * zero. Setting all null intervals to 1 fixes the problem and - * some other divisions by zero which could happen. - */ - for (i = 0; i < n; ++i) { - interval = le32_to_cpup((__le32 *)&buffer[26+4*i]); - *(*intervals)++ = interval ? interval : 1; - } - - /* Make sure that the default frame interval stays between - * the boundaries. - */ - n -= frame->bFrameIntervalType ? 1 : 2; - frame->dwDefaultFrameInterval = - min(frame->dwFrameInterval[n], - max(frame->dwFrameInterval[0], - frame->dwDefaultFrameInterval)); - - uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n", - frame->wWidth, frame->wHeight, - 10000000/frame->dwDefaultFrameInterval, - (100000000/frame->dwDefaultFrameInterval)%10); - - format->nframes++; - buflen -= buffer[0]; - buffer += buffer[0]; - } - - if (buflen > 2 && buffer[2] == VS_STILL_IMAGE_FRAME) { - buflen -= buffer[0]; - buffer += buffer[0]; - } - - if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { - if (buflen < 6) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d COLORFORMAT error\n", - dev->udev->devnum, - alts->desc.bInterfaceNumber); - return -EINVAL; - } - - format->colorspace = uvc_colorspace(buffer[3]); - - buflen -= buffer[0]; - buffer += buffer[0]; - } - - return buffer - start; -} - -static int uvc_parse_streaming(struct uvc_device *dev, - struct usb_interface *intf) -{ - struct uvc_streaming *streaming = NULL; - struct uvc_format *format; - struct uvc_frame *frame; - struct usb_host_interface *alts = &intf->altsetting[0]; - unsigned char *_buffer, *buffer = alts->extra; - int _buflen, buflen = alts->extralen; - unsigned int nformats = 0, nframes = 0, nintervals = 0; - unsigned int size, i, n, p; - __u32 *interval; - __u16 psize; - int ret = -EINVAL; - - if (intf->cur_altsetting->desc.bInterfaceSubClass - != SC_VIDEOSTREAMING) { - uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a " - "video streaming interface\n", dev->udev->devnum, - intf->altsetting[0].desc.bInterfaceNumber); - return -EINVAL; - } - - if (usb_driver_claim_interface(&uvc_driver.driver, intf, dev)) { - uvc_trace(UVC_TRACE_DESCR, "device %d interface %d is already " - "claimed\n", dev->udev->devnum, - intf->altsetting[0].desc.bInterfaceNumber); - return -EINVAL; - } - - streaming = kzalloc(sizeof *streaming, GFP_KERNEL); - if (streaming == NULL) { - usb_driver_release_interface(&uvc_driver.driver, intf); - return -EINVAL; - } - - mutex_init(&streaming->mutex); - streaming->intf = usb_get_intf(intf); - streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; - - /* The Pico iMage webcam has its class-specific interface descriptors - * after the endpoint descriptors. - */ - if (buflen == 0) { - for (i = 0; i < alts->desc.bNumEndpoints; ++i) { - struct usb_host_endpoint *ep = &alts->endpoint[i]; - - if (ep->extralen == 0) - continue; - - if (ep->extralen > 2 && - ep->extra[1] == USB_DT_CS_INTERFACE) { - uvc_trace(UVC_TRACE_DESCR, "trying extra data " - "from endpoint %u.\n", i); - buffer = alts->endpoint[i].extra; - buflen = alts->endpoint[i].extralen; - break; - } - } - } - - /* Skip the standard interface descriptors. */ - while (buflen > 2 && buffer[1] != USB_DT_CS_INTERFACE) { - buflen -= buffer[0]; - buffer += buffer[0]; - } - - if (buflen <= 2) { - uvc_trace(UVC_TRACE_DESCR, "no class-specific streaming " - "interface descriptors found.\n"); - goto error; - } - - /* Parse the header descriptor. */ - if (buffer[2] == VS_OUTPUT_HEADER) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " - "%d OUTPUT HEADER descriptor is not supported.\n", - dev->udev->devnum, alts->desc.bInterfaceNumber); - goto error; - } else if (buffer[2] == VS_INPUT_HEADER) { - p = buflen >= 5 ? buffer[3] : 0; - n = buflen >= 12 ? buffer[12] : 0; - - if (buflen < 13 + p*n || buffer[2] != VS_INPUT_HEADER) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " - "interface %d INPUT HEADER descriptor is " - "invalid.\n", dev->udev->devnum, - alts->desc.bInterfaceNumber); - goto error; - } - - streaming->header.bNumFormats = p; - streaming->header.bEndpointAddress = buffer[6]; - streaming->header.bmInfo = buffer[7]; - streaming->header.bTerminalLink = buffer[8]; - streaming->header.bStillCaptureMethod = buffer[9]; - streaming->header.bTriggerSupport = buffer[10]; - streaming->header.bTriggerUsage = buffer[11]; - streaming->header.bControlSize = n; - - streaming->header.bmaControls = kmalloc(p*n, GFP_KERNEL); - if (streaming->header.bmaControls == NULL) { - ret = -ENOMEM; - goto error; - } - - memcpy(streaming->header.bmaControls, &buffer[13], p*n); - } else { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " - "%d HEADER descriptor not found.\n", dev->udev->devnum, - alts->desc.bInterfaceNumber); - goto error; - } - - buflen -= buffer[0]; - buffer += buffer[0]; - - _buffer = buffer; - _buflen = buflen; - - /* Count the format and frame descriptors. */ - while (_buflen > 2) { - switch (_buffer[2]) { - case VS_FORMAT_UNCOMPRESSED: - case VS_FORMAT_MJPEG: - case VS_FORMAT_FRAME_BASED: - nformats++; - break; - - case VS_FORMAT_DV: - /* DV format has no frame descriptor. We will create a - * dummy frame descriptor with a dummy frame interval. - */ - nformats++; - nframes++; - nintervals++; - break; - - case VS_FORMAT_MPEG2TS: - case VS_FORMAT_STREAM_BASED: - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " - "interface %d FORMAT %u is not supported.\n", - dev->udev->devnum, - alts->desc.bInterfaceNumber, _buffer[2]); - break; - - case VS_FRAME_UNCOMPRESSED: - case VS_FRAME_MJPEG: - nframes++; - if (_buflen > 25) - nintervals += _buffer[25] ? _buffer[25] : 3; - break; - - case VS_FRAME_FRAME_BASED: - nframes++; - if (_buflen > 21) - nintervals += _buffer[21] ? _buffer[21] : 3; - break; - } - - _buflen -= _buffer[0]; - _buffer += _buffer[0]; - } - - if (nformats == 0) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface " - "%d has no supported formats defined.\n", - dev->udev->devnum, alts->desc.bInterfaceNumber); - goto error; - } - - size = nformats * sizeof *format + nframes * sizeof *frame - + nintervals * sizeof *interval; - format = kzalloc(size, GFP_KERNEL); - if (format == NULL) { - ret = -ENOMEM; - goto error; - } - - frame = (struct uvc_frame *)&format[nformats]; - interval = (__u32 *)&frame[nframes]; - - streaming->format = format; - streaming->nformats = nformats; - - /* Parse the format descriptors. */ - while (buflen > 2) { - switch (buffer[2]) { - case VS_FORMAT_UNCOMPRESSED: - case VS_FORMAT_MJPEG: - case VS_FORMAT_DV: - case VS_FORMAT_FRAME_BASED: - format->frame = frame; - ret = uvc_parse_format(dev, streaming, format, - &interval, buffer, buflen); - if (ret < 0) - goto error; - - frame += format->nframes; - format++; - - buflen -= ret; - buffer += ret; - continue; - - default: - break; - } - - buflen -= buffer[0]; - buffer += buffer[0]; - } - - /* Parse the alternate settings to find the maximum bandwidth. */ - for (i = 0; i < intf->num_altsetting; ++i) { - struct usb_host_endpoint *ep; - alts = &intf->altsetting[i]; - ep = uvc_find_endpoint(alts, - streaming->header.bEndpointAddress); - if (ep == NULL) - continue; - - psize = le16_to_cpu(ep->desc.wMaxPacketSize); - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); - if (psize > streaming->maxpsize) - streaming->maxpsize = psize; - } - - list_add_tail(&streaming->list, &dev->streaming); - return 0; - -error: - usb_driver_release_interface(&uvc_driver.driver, intf); - usb_put_intf(intf); - kfree(streaming->format); - kfree(streaming->header.bmaControls); - kfree(streaming); - return ret; -} - -/* Parse vendor-specific extensions. */ -static int uvc_parse_vendor_control(struct uvc_device *dev, - const unsigned char *buffer, int buflen) -{ - struct usb_device *udev = dev->udev; - struct usb_host_interface *alts = dev->intf->cur_altsetting; - struct uvc_entity *unit; - unsigned int n, p; - int handled = 0; - - switch (le16_to_cpu(dev->udev->descriptor.idVendor)) { - case 0x046d: /* Logitech */ - if (buffer[1] != 0x41 || buffer[2] != 0x01) - break; - - /* Logitech implements several vendor specific functions - * through vendor specific extension units (LXU). - * - * The LXU descriptors are similar to XU descriptors - * (see "USB Device Video Class for Video Devices", section - * 3.7.2.6 "Extension Unit Descriptor") with the following - * differences: - * - * ---------------------------------------------------------- - * 0 bLength 1 Number - * Size of this descriptor, in bytes: 24+p+n*2 - * ---------------------------------------------------------- - * 23+p+n bmControlsType N Bitmap - * Individual bits in the set are defined: - * 0: Absolute - * 1: Relative - * - * This bitset is mapped exactly the same as bmControls. - * ---------------------------------------------------------- - * 23+p+n*2 bReserved 1 Boolean - * ---------------------------------------------------------- - * 24+p+n*2 iExtension 1 Index - * Index of a string descriptor that describes this - * extension unit. - * ---------------------------------------------------------- - */ - p = buflen >= 22 ? buffer[21] : 0; - n = buflen >= 25 + p ? buffer[22+p] : 0; - - if (buflen < 25 + p + 2*n) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d EXTENSION_UNIT error\n", - udev->devnum, alts->desc.bInterfaceNumber); - break; - } - - unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL); - if (unit == NULL) - return -ENOMEM; - - unit->id = buffer[3]; - unit->type = VC_EXTENSION_UNIT; - memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); - unit->extension.bNumControls = buffer[20]; - unit->extension.bNrInPins = - le16_to_cpup((__le16 *)&buffer[21]); - unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; - memcpy(unit->extension.baSourceID, &buffer[22], p); - unit->extension.bControlSize = buffer[22+p]; - unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; - unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit - + p + n; - memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); - - if (buffer[24+p+2*n] != 0) - usb_string(udev, buffer[24+p+2*n], unit->name, - sizeof unit->name); - else - sprintf(unit->name, "Extension %u", buffer[3]); - - list_add_tail(&unit->list, &dev->entities); - handled = 1; - break; - } - - return handled; -} - -static int uvc_parse_standard_control(struct uvc_device *dev, - const unsigned char *buffer, int buflen) -{ - struct usb_device *udev = dev->udev; - struct uvc_entity *unit, *term; - struct usb_interface *intf; - struct usb_host_interface *alts = dev->intf->cur_altsetting; - unsigned int i, n, p, len; - __u16 type; - - switch (buffer[2]) { - case VC_HEADER: - n = buflen >= 12 ? buffer[11] : 0; - - if (buflen < 12 || buflen < 12 + n) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d HEADER error\n", udev->devnum, - alts->desc.bInterfaceNumber); - return -EINVAL; - } - - dev->uvc_version = le16_to_cpup((__le16 *)&buffer[3]); - dev->clock_frequency = le32_to_cpup((__le32 *)&buffer[7]); - - /* Parse all USB Video Streaming interfaces. */ - for (i = 0; i < n; ++i) { - intf = usb_ifnum_to_if(udev, buffer[12+i]); - if (intf == NULL) { - uvc_trace(UVC_TRACE_DESCR, "device %d " - "interface %d doesn't exists\n", - udev->devnum, i); - continue; - } - - uvc_parse_streaming(dev, intf); - } - break; - - case VC_INPUT_TERMINAL: - if (buflen < 8) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d INPUT_TERMINAL error\n", - udev->devnum, alts->desc.bInterfaceNumber); - return -EINVAL; - } - - /* Make sure the terminal type MSB is not null, otherwise it - * could be confused with a unit. - */ - type = le16_to_cpup((__le16 *)&buffer[4]); - if ((type & 0xff00) == 0) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d INPUT_TERMINAL %d has invalid " - "type 0x%04x, skipping\n", udev->devnum, - alts->desc.bInterfaceNumber, - buffer[3], type); - return 0; - } - - n = 0; - p = 0; - len = 8; - - if (type == ITT_CAMERA) { - n = buflen >= 15 ? buffer[14] : 0; - len = 15; - - } else if (type == ITT_MEDIA_TRANSPORT_INPUT) { - n = buflen >= 9 ? buffer[8] : 0; - p = buflen >= 10 + n ? buffer[9+n] : 0; - len = 10; - } - - if (buflen < len + n + p) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d INPUT_TERMINAL error\n", - udev->devnum, alts->desc.bInterfaceNumber); - return -EINVAL; - } - - term = kzalloc(sizeof *term + n + p, GFP_KERNEL); - if (term == NULL) - return -ENOMEM; - - term->id = buffer[3]; - term->type = type | UVC_TERM_INPUT; - - if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) { - term->camera.bControlSize = n; - term->camera.bmControls = (__u8 *)term + sizeof *term; - term->camera.wObjectiveFocalLengthMin = - le16_to_cpup((__le16 *)&buffer[8]); - term->camera.wObjectiveFocalLengthMax = - le16_to_cpup((__le16 *)&buffer[10]); - term->camera.wOcularFocalLength = - le16_to_cpup((__le16 *)&buffer[12]); - memcpy(term->camera.bmControls, &buffer[15], n); - } else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) { - term->media.bControlSize = n; - term->media.bmControls = (__u8 *)term + sizeof *term; - term->media.bTransportModeSize = p; - term->media.bmTransportModes = (__u8 *)term - + sizeof *term + n; - memcpy(term->media.bmControls, &buffer[9], n); - memcpy(term->media.bmTransportModes, &buffer[10+n], p); - } - - if (buffer[7] != 0) - usb_string(udev, buffer[7], term->name, - sizeof term->name); - else if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) - sprintf(term->name, "Camera %u", buffer[3]); - else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) - sprintf(term->name, "Media %u", buffer[3]); - else - sprintf(term->name, "Input %u", buffer[3]); - - list_add_tail(&term->list, &dev->entities); - break; - - case VC_OUTPUT_TERMINAL: - if (buflen < 9) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d OUTPUT_TERMINAL error\n", - udev->devnum, alts->desc.bInterfaceNumber); - return -EINVAL; - } - - /* Make sure the terminal type MSB is not null, otherwise it - * could be confused with a unit. - */ - type = le16_to_cpup((__le16 *)&buffer[4]); - if ((type & 0xff00) == 0) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d OUTPUT_TERMINAL %d has invalid " - "type 0x%04x, skipping\n", udev->devnum, - alts->desc.bInterfaceNumber, buffer[3], type); - return 0; - } - - term = kzalloc(sizeof *term, GFP_KERNEL); - if (term == NULL) - return -ENOMEM; - - term->id = buffer[3]; - term->type = type | UVC_TERM_OUTPUT; - term->output.bSourceID = buffer[7]; - - if (buffer[8] != 0) - usb_string(udev, buffer[8], term->name, - sizeof term->name); - else - sprintf(term->name, "Output %u", buffer[3]); - - list_add_tail(&term->list, &dev->entities); - break; - - case VC_SELECTOR_UNIT: - p = buflen >= 5 ? buffer[4] : 0; - - if (buflen < 5 || buflen < 6 + p) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d SELECTOR_UNIT error\n", - udev->devnum, alts->desc.bInterfaceNumber); - return -EINVAL; - } - - unit = kzalloc(sizeof *unit + p, GFP_KERNEL); - if (unit == NULL) - return -ENOMEM; - - unit->id = buffer[3]; - unit->type = buffer[2]; - unit->selector.bNrInPins = buffer[4]; - unit->selector.baSourceID = (__u8 *)unit + sizeof *unit; - memcpy(unit->selector.baSourceID, &buffer[5], p); - - if (buffer[5+p] != 0) - usb_string(udev, buffer[5+p], unit->name, - sizeof unit->name); - else - sprintf(unit->name, "Selector %u", buffer[3]); - - list_add_tail(&unit->list, &dev->entities); - break; - - case VC_PROCESSING_UNIT: - n = buflen >= 8 ? buffer[7] : 0; - p = dev->uvc_version >= 0x0110 ? 10 : 9; - - if (buflen < p + n) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d PROCESSING_UNIT error\n", - udev->devnum, alts->desc.bInterfaceNumber); - return -EINVAL; - } - - unit = kzalloc(sizeof *unit + n, GFP_KERNEL); - if (unit == NULL) - return -ENOMEM; - - unit->id = buffer[3]; - unit->type = buffer[2]; - unit->processing.bSourceID = buffer[4]; - unit->processing.wMaxMultiplier = - le16_to_cpup((__le16 *)&buffer[5]); - unit->processing.bControlSize = buffer[7]; - unit->processing.bmControls = (__u8 *)unit + sizeof *unit; - memcpy(unit->processing.bmControls, &buffer[8], n); - if (dev->uvc_version >= 0x0110) - unit->processing.bmVideoStandards = buffer[9+n]; - - if (buffer[8+n] != 0) - usb_string(udev, buffer[8+n], unit->name, - sizeof unit->name); - else - sprintf(unit->name, "Processing %u", buffer[3]); - - list_add_tail(&unit->list, &dev->entities); - break; - - case VC_EXTENSION_UNIT: - p = buflen >= 22 ? buffer[21] : 0; - n = buflen >= 24 + p ? buffer[22+p] : 0; - - if (buflen < 24 + p + n) { - uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " - "interface %d EXTENSION_UNIT error\n", - udev->devnum, alts->desc.bInterfaceNumber); - return -EINVAL; - } - - unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL); - if (unit == NULL) - return -ENOMEM; - - unit->id = buffer[3]; - unit->type = buffer[2]; - memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); - unit->extension.bNumControls = buffer[20]; - unit->extension.bNrInPins = - le16_to_cpup((__le16 *)&buffer[21]); - unit->extension.baSourceID = (__u8 *)unit + sizeof *unit; - memcpy(unit->extension.baSourceID, &buffer[22], p); - unit->extension.bControlSize = buffer[22+p]; - unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; - memcpy(unit->extension.bmControls, &buffer[23+p], n); - - if (buffer[23+p+n] != 0) - usb_string(udev, buffer[23+p+n], unit->name, - sizeof unit->name); - else - sprintf(unit->name, "Extension %u", buffer[3]); - - list_add_tail(&unit->list, &dev->entities); - break; - - default: - uvc_trace(UVC_TRACE_DESCR, "Found an unknown CS_INTERFACE " - "descriptor (%u)\n", buffer[2]); - break; - } - - return 0; -} - -static int uvc_parse_control(struct uvc_device *dev) -{ - struct usb_host_interface *alts = dev->intf->cur_altsetting; - unsigned char *buffer = alts->extra; - int buflen = alts->extralen; - int ret; - - /* Parse the default alternate setting only, as the UVC specification - * defines a single alternate setting, the default alternate setting - * zero. - */ - - while (buflen > 2) { - if (uvc_parse_vendor_control(dev, buffer, buflen) || - buffer[1] != USB_DT_CS_INTERFACE) - goto next_descriptor; - - if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0) - return ret; - -next_descriptor: - buflen -= buffer[0]; - buffer += buffer[0]; - } - - /* Check if the optional status endpoint is present. */ - if (alts->desc.bNumEndpoints == 1) { - struct usb_host_endpoint *ep = &alts->endpoint[0]; - struct usb_endpoint_descriptor *desc = &ep->desc; - - if (usb_endpoint_is_int_in(desc) && - le16_to_cpu(desc->wMaxPacketSize) >= 8 && - desc->bInterval != 0) { - uvc_trace(UVC_TRACE_DESCR, "Found a Status endpoint " - "(addr %02x).\n", desc->bEndpointAddress); - dev->int_ep = ep; - } - } - - return 0; -} - -/* ------------------------------------------------------------------------ - * USB probe and disconnect - */ - -/* - * Unregister the video devices. - */ -static void uvc_unregister_video(struct uvc_device *dev) -{ - if (dev->video.vdev) { - if (dev->video.vdev->minor == -1) - video_device_release(dev->video.vdev); - else - video_unregister_device(dev->video.vdev); - dev->video.vdev = NULL; - } -} - -/* - * Scan the UVC descriptors to locate a chain starting at an Output Terminal - * and containing the following units: - * - * - a USB Streaming Output Terminal - * - zero or one Processing Unit - * - zero, one or mode single-input Selector Units - * - zero or one multiple-input Selector Units, provided all inputs are - * connected to input terminals - * - zero, one or mode single-input Extension Units - * - one Camera Input Terminal, or one or more External terminals. - * - * A side forward scan is made on each detected entity to check for additional - * extension units. - */ -static int uvc_scan_chain_entity(struct uvc_video_device *video, - struct uvc_entity *entity) -{ - switch (UVC_ENTITY_TYPE(entity)) { - case VC_EXTENSION_UNIT: - if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- XU %d", entity->id); - - if (entity->extension.bNrInPins != 1) { - uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more " - "than 1 input pin.\n", entity->id); - return -1; - } - - list_add_tail(&entity->chain, &video->extensions); - break; - - case VC_PROCESSING_UNIT: - if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- PU %d", entity->id); - - if (video->processing != NULL) { - uvc_trace(UVC_TRACE_DESCR, "Found multiple " - "Processing Units in chain.\n"); - return -1; - } - - video->processing = entity; - break; - - case VC_SELECTOR_UNIT: - if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- SU %d", entity->id); - - /* Single-input selector units are ignored. */ - if (entity->selector.bNrInPins == 1) - break; - - if (video->selector != NULL) { - uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector " - "Units in chain.\n"); - return -1; - } - - video->selector = entity; - break; - - case ITT_VENDOR_SPECIFIC: - case ITT_CAMERA: - case ITT_MEDIA_TRANSPORT_INPUT: - if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- IT %d\n", entity->id); - - list_add_tail(&entity->chain, &video->iterms); - break; - - default: - uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type " - "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity)); - return -1; - } - - return 0; -} - -static int uvc_scan_chain_forward(struct uvc_video_device *video, - struct uvc_entity *entity, struct uvc_entity *prev) -{ - struct uvc_entity *forward; - int found; - - /* Forward scan */ - forward = NULL; - found = 0; - - while (1) { - forward = uvc_entity_by_reference(video->dev, entity->id, - forward); - if (forward == NULL) - break; - - if (UVC_ENTITY_TYPE(forward) != VC_EXTENSION_UNIT || - forward == prev) - continue; - - if (forward->extension.bNrInPins != 1) { - uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has" - "more than 1 input pin.\n", entity->id); - return -1; - } - - list_add_tail(&forward->chain, &video->extensions); - if (uvc_trace_param & UVC_TRACE_PROBE) { - if (!found) - printk(" (-> XU"); - - printk(" %d", forward->id); - found = 1; - } - } - if (found) - printk(")"); - - return 0; -} - -static int uvc_scan_chain_backward(struct uvc_video_device *video, - struct uvc_entity *entity) -{ - struct uvc_entity *term; - int id = -1, i; - - switch (UVC_ENTITY_TYPE(entity)) { - case VC_EXTENSION_UNIT: - id = entity->extension.baSourceID[0]; - break; - - case VC_PROCESSING_UNIT: - id = entity->processing.bSourceID; - break; - - case VC_SELECTOR_UNIT: - /* Single-input selector units are ignored. */ - if (entity->selector.bNrInPins == 1) { - id = entity->selector.baSourceID[0]; - break; - } - - if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" <- IT"); - - video->selector = entity; - for (i = 0; i < entity->selector.bNrInPins; ++i) { - id = entity->selector.baSourceID[i]; - term = uvc_entity_by_id(video->dev, id); - if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) { - uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " - "input %d isn't connected to an " - "input terminal\n", entity->id, i); - return -1; - } - - if (uvc_trace_param & UVC_TRACE_PROBE) - printk(" %d", term->id); - - list_add_tail(&term->chain, &video->iterms); - uvc_scan_chain_forward(video, term, entity); - } - - if (uvc_trace_param & UVC_TRACE_PROBE) - printk("\n"); - - id = 0; - break; - } - - return id; -} - -static int uvc_scan_chain(struct uvc_video_device *video) -{ - struct uvc_entity *entity, *prev; - int id; - - entity = video->oterm; - uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); - id = entity->output.bSourceID; - while (id != 0) { - prev = entity; - entity = uvc_entity_by_id(video->dev, id); - if (entity == NULL) { - uvc_trace(UVC_TRACE_DESCR, "Found reference to " - "unknown entity %d.\n", id); - return -1; - } - - /* Process entity */ - if (uvc_scan_chain_entity(video, entity) < 0) - return -1; - - /* Forward scan */ - if (uvc_scan_chain_forward(video, entity, prev) < 0) - return -1; - - /* Stop when a terminal is found. */ - if (!UVC_ENTITY_IS_UNIT(entity)) - break; - - /* Backward scan */ - id = uvc_scan_chain_backward(video, entity); - if (id < 0) - return id; - } - - /* Initialize the video buffers queue. */ - uvc_queue_init(&video->queue); - - return 0; -} - -/* - * Register the video devices. - * - * The driver currently supports a single video device per control interface - * only. The terminal and units must match the following structure: - * - * ITT_CAMERA -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING - * - * The Extension Units, if present, must have a single input pin. The - * Processing Unit and Extension Units can be in any order. Additional - * Extension Units connected to the main chain as single-unit branches are - * also supported. - */ -static int uvc_register_video(struct uvc_device *dev) -{ - struct video_device *vdev; - struct uvc_entity *term; - int found = 0, ret; - - /* Check if the control interface matches the structure we expect. */ - list_for_each_entry(term, &dev->entities, list) { - struct uvc_streaming *streaming; - - if (UVC_ENTITY_TYPE(term) != TT_STREAMING) - continue; - - memset(&dev->video, 0, sizeof dev->video); - mutex_init(&dev->video.ctrl_mutex); - INIT_LIST_HEAD(&dev->video.iterms); - INIT_LIST_HEAD(&dev->video.extensions); - dev->video.oterm = term; - dev->video.dev = dev; - if (uvc_scan_chain(&dev->video) < 0) - continue; - - list_for_each_entry(streaming, &dev->streaming, list) { - if (streaming->header.bTerminalLink == term->id) { - dev->video.streaming = streaming; - found = 1; - break; - } - } - - if (found) - break; - } - - if (!found) { - uvc_printk(KERN_INFO, "No valid video chain found.\n"); - return -1; - } - - if (uvc_trace_param & UVC_TRACE_PROBE) { - uvc_printk(KERN_INFO, "Found a valid video chain ("); - list_for_each_entry(term, &dev->video.iterms, chain) { - printk("%d", term->id); - if (term->chain.next != &dev->video.iterms) - printk(","); - } - printk(" -> %d).\n", dev->video.oterm->id); - } - - /* Initialize the streaming interface with default streaming - * parameters. - */ - if ((ret = uvc_video_init(&dev->video)) < 0) { - uvc_printk(KERN_ERR, "Failed to initialize the device " - "(%d).\n", ret); - return ret; - } - - /* Register the device with V4L. */ - vdev = video_device_alloc(); - if (vdev == NULL) - return -1; - - /* We already hold a reference to dev->udev. The video device will be - * unregistered before the reference is released, so we don't need to - * get another one. - */ - vdev->dev = &dev->intf->dev; - vdev->type = 0; - vdev->type2 = 0; - vdev->minor = -1; - vdev->fops = &uvc_fops; - vdev->release = video_device_release; - strncpy(vdev->name, dev->name, sizeof vdev->name); - - /* Set the driver data before calling video_register_device, otherwise - * uvc_v4l2_open might race us. - * - * FIXME: usb_set_intfdata hasn't been called so far. Is that a - * problem ? Does any function which could be called here get - * a pointer to the usb_interface ? - */ - dev->video.vdev = vdev; - video_set_drvdata(vdev, &dev->video); - - if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) { - dev->video.vdev = NULL; - video_device_release(vdev); - return -1; - } - - return 0; -} - -/* - * Delete the UVC device. - * - * Called by the kernel when the last reference to the uvc_device structure - * is released. - * - * Unregistering the video devices is done here because every opened instance - * must be closed before the device can be unregistered. An alternative would - * have been to use another reference count for uvc_v4l2_open/uvc_release, and - * unregister the video devices on disconnect when that reference count drops - * to zero. - * - * As this function is called after or during disconnect(), all URBs have - * already been canceled by the USB core. There is no need to kill the - * interrupt URB manually. - */ -void uvc_delete(struct kref *kref) -{ - struct uvc_device *dev = container_of(kref, struct uvc_device, kref); - struct list_head *p, *n; - - /* Unregister the video device */ - uvc_unregister_video(dev); - usb_put_intf(dev->intf); - usb_put_dev(dev->udev); - - uvc_status_cleanup(dev); - uvc_ctrl_cleanup_device(dev); - - list_for_each_safe(p, n, &dev->entities) { - struct uvc_entity *entity; - entity = list_entry(p, struct uvc_entity, list); - kfree(entity); - } - - list_for_each_safe(p, n, &dev->streaming) { - struct uvc_streaming *streaming; - streaming = list_entry(p, struct uvc_streaming, list); - usb_driver_release_interface(&uvc_driver.driver, - streaming->intf); - usb_put_intf(streaming->intf); - kfree(streaming->format); - kfree(streaming->header.bmaControls); - kfree(streaming); - } - - kfree(dev); -} - -static int uvc_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct uvc_device *dev; - int ret; - - if (id->idVendor && id->idProduct) - uvc_trace(UVC_TRACE_PROBE, "Probing known UVC device %s " - "(%04x:%04x)\n", udev->devpath, id->idVendor, - id->idProduct); - else - uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n", - udev->devpath); - - /* Allocate memory for the device and initialize it */ - if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL) - return -ENOMEM; - - INIT_LIST_HEAD(&dev->entities); - INIT_LIST_HEAD(&dev->streaming); - kref_init(&dev->kref); - - dev->udev = usb_get_dev(udev); - dev->intf = usb_get_intf(intf); - dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; - dev->quirks = id->driver_info | uvc_quirks_param; - - if (udev->product != NULL) - strncpy(dev->name, udev->product, sizeof dev->name); - else - snprintf(dev->name, sizeof dev->name, - "UVC Camera (%04x:%04x)", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - /* Parse the Video Class control descriptor */ - if (uvc_parse_control(dev) < 0) { - uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC " - "descriptors.\n"); - goto error; - } - - uvc_printk(KERN_INFO, "Found UVC %u.%02u device %s (%04x:%04x)\n", - dev->uvc_version >> 8, dev->uvc_version & 0xff, - udev->product ? udev->product : "", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - if (uvc_quirks_param != 0) { - uvc_printk(KERN_INFO, "Forcing device quirks 0x%x by module " - "parameter for testing purpose.\n", uvc_quirks_param); - uvc_printk(KERN_INFO, "Please report required quirks to the " - "linux-uvc-devel mailing list.\n"); - } - - /* Initialize controls */ - if (uvc_ctrl_init_device(dev) < 0) - goto error; - - /* Register the video devices */ - if (uvc_register_video(dev) < 0) - goto error; - - /* Save our data pointer in the interface data */ - usb_set_intfdata(intf, dev); - - /* Initialize the interrupt URB */ - if ((ret = uvc_status_init(dev)) < 0) { - uvc_printk(KERN_INFO, "Unable to initialize the status " - "endpoint (%d), status interrupt will not be " - "supported.\n", ret); - } - - uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n"); - return 0; - -error: - kref_put(&dev->kref, uvc_delete); - return -ENODEV; -} - -static void uvc_disconnect(struct usb_interface *intf) -{ - struct uvc_device *dev = usb_get_intfdata(intf); - - /* Set the USB interface data to NULL. This can be done outside the - * lock, as there's no other reader. - */ - usb_set_intfdata(intf, NULL); - - if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING) - return; - - /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide - * lock is needed to prevent uvc_disconnect from releasing its - * reference to the uvc_device instance after uvc_v4l2_open() received - * the pointer to the device (video_devdata) but before it got the - * chance to increase the reference count (kref_get). - */ - mutex_lock(&uvc_driver.open_mutex); - - dev->state |= UVC_DEV_DISCONNECTED; - kref_put(&dev->kref, uvc_delete); - - mutex_unlock(&uvc_driver.open_mutex); -} - -static int uvc_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct uvc_device *dev = usb_get_intfdata(intf); - - uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n", - intf->cur_altsetting->desc.bInterfaceNumber); - - /* Controls are cached on the fly so they don't need to be saved. */ - if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) - return uvc_status_suspend(dev); - - if (dev->video.streaming->intf != intf) { - uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB " - "interface mismatch.\n"); - return -EINVAL; - } - - return uvc_video_suspend(&dev->video); -} - -static int uvc_resume(struct usb_interface *intf) -{ - struct uvc_device *dev = usb_get_intfdata(intf); - int ret; - - uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", - intf->cur_altsetting->desc.bInterfaceNumber); - - if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) { - if ((ret = uvc_ctrl_resume_device(dev)) < 0) - return ret; - - return uvc_status_resume(dev); - } - - if (dev->video.streaming->intf != intf) { - uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB " - "interface mismatch.\n"); - return -EINVAL; - } - - return uvc_video_resume(&dev->video); -} - -/* ------------------------------------------------------------------------ - * Driver initialization and cleanup - */ - -/* - * The Logitech cameras listed below have their interface class set to - * VENDOR_SPEC because they don't announce themselves as UVC devices, even - * though they are compliant. - */ -static struct usb_device_id uvc_ids[] = { - /* ALi M5606 (Clevo M540SR) */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x0402, - .idProduct = 0x5606, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Creative Live! Optia */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x041e, - .idProduct = 0x4057, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Microsoft Lifecam NX-6000 */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x045e, - .idProduct = 0x00f8, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Microsoft Lifecam VX-7000 */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x045e, - .idProduct = 0x0723, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Logitech Quickcam Fusion */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x046d, - .idProduct = 0x08c1, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0 }, - /* Logitech Quickcam Orbit MP */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x046d, - .idProduct = 0x08c2, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0 }, - /* Logitech Quickcam Pro for Notebook */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x046d, - .idProduct = 0x08c3, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0 }, - /* Logitech Quickcam Pro 5000 */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x046d, - .idProduct = 0x08c5, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0 }, - /* Logitech Quickcam OEM Dell Notebook */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x046d, - .idProduct = 0x08c6, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0 }, - /* Logitech Quickcam OEM Cisco VT Camera II */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x046d, - .idProduct = 0x08c7, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0 }, - /* Apple Built-In iSight */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x05ac, - .idProduct = 0x8501, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - | UVC_QUIRK_BUILTIN_ISIGHT }, - /* Genesys Logic USB 2.0 PC Camera */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x05e3, - .idProduct = 0x0505, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* Silicon Motion SM371 */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x090c, - .idProduct = 0xb371, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* MT6227 */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x0e8d, - .idProduct = 0x0004, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Syntek (HP Spartan) */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x174f, - .idProduct = 0x5212, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* Syntek (Asus U3S) */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x174f, - .idProduct = 0x8a33, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* Ecamm Pico iMage */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x18cd, - .idProduct = 0xcafe, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, - /* Bodelin ProScopeHR */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_DEV_HI - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x19ab, - .idProduct = 0x1000, - .bcdDevice_hi = 0x0126, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_STATUS_INTERVAL }, - /* SiGma Micro USB Web Camera */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x1c4f, - .idProduct = 0x3000, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX - | UVC_QUIRK_IGNORE_SELECTOR_UNIT}, - /* Acer OEM Webcam - Unknown vendor */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0100, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Packard Bell OEM Webcam */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0101, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Acer Crystal Eye webcam */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0102, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Acer OrbiCam - Unknown vendor */ - { .match_flags = USB_DEVICE_ID_MATCH_DEVICE - | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x5986, - .idProduct = 0x0200, - .bInterfaceClass = USB_CLASS_VIDEO, - .bInterfaceSubClass = 1, - .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, - /* Generic USB Video Class */ - { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, - {} -}; - -MODULE_DEVICE_TABLE(usb, uvc_ids); - -struct uvc_driver uvc_driver = { - .driver = { - .name = "uvcvideo", - .probe = uvc_probe, - .disconnect = uvc_disconnect, - .suspend = uvc_suspend, - .resume = uvc_resume, - .id_table = uvc_ids, - .supports_autosuspend = 1, - }, -}; - -static int __init uvc_init(void) -{ - int result; - - INIT_LIST_HEAD(&uvc_driver.devices); - INIT_LIST_HEAD(&uvc_driver.controls); - mutex_init(&uvc_driver.open_mutex); - mutex_init(&uvc_driver.ctrl_mutex); - - uvc_ctrl_init(); - - result = usb_register(&uvc_driver.driver); - if (result == 0) - printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n"); - return result; -} - -static void __exit uvc_cleanup(void) -{ - usb_deregister(&uvc_driver.driver); -} - -module_init(uvc_init); -module_exit(uvc_cleanup); - -module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(quirks, "Forced device quirks"); -module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(trace, "Trace level bitmask"); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); diff --git a/trunk/drivers/media/video/uvc/uvc_isight.c b/trunk/drivers/media/video/uvc/uvc_isight.c deleted file mode 100644 index 37bdefdbead5..000000000000 --- a/trunk/drivers/media/video/uvc/uvc_isight.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * uvc_isight.c -- USB Video Class driver - iSight support - * - * Copyright (C) 2006-2007 - * Ivan N. Zlatev - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include - -#include "uvcvideo.h" - -/* Built-in iSight webcams implements most of UVC 1.0 except a - * different packet format. Instead of sending a header at the - * beginning of each isochronous transfer payload, the webcam sends a - * single header per image (on its own in a packet), followed by - * packets containing data only. - * - * Offset Size (bytes) Description - * ------------------------------------------------------------------ - * 0x00 1 Header length - * 0x01 1 Flags (UVC-compliant) - * 0x02 4 Always equal to '11223344' - * 0x06 8 Always equal to 'deadbeefdeadface' - * 0x0e 16 Unknown - * - * The header can be prefixed by an optional, unknown-purpose byte. - */ - -static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, - const __u8 *data, unsigned int len) -{ - static const __u8 hdr[] = { - 0x11, 0x22, 0x33, 0x44, - 0xde, 0xad, 0xbe, 0xef, - 0xde, 0xad, 0xfa, 0xce - }; - - unsigned int maxlen, nbytes; - __u8 *mem; - int is_header = 0; - - if (buf == NULL) - return 0; - - if ((len >= 14 && memcmp(&data[2], hdr, 12) == 0) || - (len >= 15 && memcmp(&data[3], hdr, 12) == 0)) { - uvc_trace(UVC_TRACE_FRAME, "iSight header found\n"); - is_header = 1; - } - - /* Synchronize to the input stream by waiting for a header packet. */ - if (buf->state != UVC_BUF_STATE_ACTIVE) { - if (!is_header) { - uvc_trace(UVC_TRACE_FRAME, "Dropping packet (out of " - "sync).\n"); - return 0; - } - - buf->state = UVC_BUF_STATE_ACTIVE; - } - - /* Mark the buffer as done if we're at the beginning of a new frame. - * - * Empty buffers (bytesused == 0) don't trigger end of frame detection - * as it doesn't make sense to return an empty buffer. - */ - if (is_header && buf->buf.bytesused != 0) { - buf->state = UVC_BUF_STATE_DONE; - return -EAGAIN; - } - - /* Copy the video data to the buffer. Skip header packets, as they - * contain no data. - */ - if (!is_header) { - maxlen = buf->buf.length - buf->buf.bytesused; - mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused; - nbytes = min(len, maxlen); - memcpy(mem, data, nbytes); - buf->buf.bytesused += nbytes; - - if (len > maxlen || buf->buf.bytesused == buf->buf.length) { - uvc_trace(UVC_TRACE_FRAME, "Frame complete " - "(overflow).\n"); - buf->state = UVC_BUF_STATE_DONE; - } - } - - return 0; -} - -void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, - struct uvc_buffer *buf) -{ - int ret, i; - - for (i = 0; i < urb->number_of_packets; ++i) { - if (urb->iso_frame_desc[i].status < 0) { - uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame " - "lost (%d).\n", - urb->iso_frame_desc[i].status); - } - - /* Decode the payload packet. - * uvc_video_decode is entered twice when a frame transition - * has been detected because the end of frame can only be - * reliably detected when the first packet of the new frame - * is processed. The first pass detects the transition and - * closes the previous frame's buffer, the second pass - * processes the data of the first payload of the new frame. - */ - do { - ret = isight_decode(&video->queue, buf, - urb->transfer_buffer + - urb->iso_frame_desc[i].offset, - urb->iso_frame_desc[i].actual_length); - - if (buf == NULL) - break; - - if (buf->state == UVC_BUF_STATE_DONE || - buf->state == UVC_BUF_STATE_ERROR) - buf = uvc_queue_next_buffer(&video->queue, buf); - } while (ret == -EAGAIN); - } -} diff --git a/trunk/drivers/media/video/uvc/uvc_queue.c b/trunk/drivers/media/video/uvc/uvc_queue.c deleted file mode 100644 index 0923f0e3b3d4..000000000000 --- a/trunk/drivers/media/video/uvc/uvc_queue.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * uvc_queue.c -- USB Video Class driver - Buffers management - * - * Copyright (C) 2005-2008 - * Laurent Pinchart (laurent.pinchart@skynet.be) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "uvcvideo.h" - -/* ------------------------------------------------------------------------ - * Video buffers queue management. - * - * Video queues is initialized by uvc_queue_init(). The function performs - * basic initialization of the uvc_video_queue struct and never fails. - * - * Video buffer allocation and freeing are performed by uvc_alloc_buffers and - * uvc_free_buffers respectively. The former acquires the video queue lock, - * while the later must be called with the lock held (so that allocation can - * free previously allocated buffers). Trying to free buffers that are mapped - * to user space will return -EBUSY. - * - * Video buffers are managed using two queues. However, unlike most USB video - * drivers which use an in queue and an out queue, we use a main queue which - * holds all queued buffers (both 'empty' and 'done' buffers), and an irq - * queue which holds empty buffers. This design (copied from video-buf) - * minimizes locking in interrupt, as only one queue is shared between - * interrupt and user contexts. - * - * Use cases - * --------- - * - * Unless stated otherwise, all operations which modify the irq buffers queue - * are protected by the irq spinlock. - * - * 1. The user queues the buffers, starts streaming and dequeues a buffer. - * - * The buffers are added to the main and irq queues. Both operations are - * protected by the queue lock, and the latert is protected by the irq - * spinlock as well. - * - * The completion handler fetches a buffer from the irq queue and fills it - * with video data. If no buffer is available (irq queue empty), the handler - * returns immediately. - * - * When the buffer is full, the completion handler removes it from the irq - * queue, marks it as ready (UVC_BUF_STATE_DONE) and wake its wait queue. - * At that point, any process waiting on the buffer will be woken up. If a - * process tries to dequeue a buffer after it has been marked ready, the - * dequeing will succeed immediately. - * - * 2. Buffers are queued, user is waiting on a buffer and the device gets - * disconnected. - * - * When the device is disconnected, the kernel calls the completion handler - * with an appropriate status code. The handler marks all buffers in the - * irq queue as being erroneous (UVC_BUF_STATE_ERROR) and wakes them up so - * that any process waiting on a buffer gets woken up. - * - * Waking up up the first buffer on the irq list is not enough, as the - * process waiting on the buffer might restart the dequeue operation - * immediately. - * - */ - -void uvc_queue_init(struct uvc_video_queue *queue) -{ - mutex_init(&queue->mutex); - spin_lock_init(&queue->irqlock); - INIT_LIST_HEAD(&queue->mainqueue); - INIT_LIST_HEAD(&queue->irqqueue); -} - -/* - * Allocate the video buffers. - * - * Pages are reserved to make sure they will not be swaped, as they will be - * filled in URB completion handler. - * - * Buffers will be individually mapped, so they must all be page aligned. - */ -int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, - unsigned int buflength) -{ - unsigned int bufsize = PAGE_ALIGN(buflength); - unsigned int i; - void *mem = NULL; - int ret; - - if (nbuffers > UVC_MAX_VIDEO_BUFFERS) - nbuffers = UVC_MAX_VIDEO_BUFFERS; - - mutex_lock(&queue->mutex); - - if ((ret = uvc_free_buffers(queue)) < 0) - goto done; - - /* Bail out if no buffers should be allocated. */ - if (nbuffers == 0) - goto done; - - /* Decrement the number of buffers until allocation succeeds. */ - for (; nbuffers > 0; --nbuffers) { - mem = vmalloc_32(nbuffers * bufsize); - if (mem != NULL) - break; - } - - if (mem == NULL) { - ret = -ENOMEM; - goto done; - } - - for (i = 0; i < nbuffers; ++i) { - memset(&queue->buffer[i], 0, sizeof queue->buffer[i]); - queue->buffer[i].buf.index = i; - queue->buffer[i].buf.m.offset = i * bufsize; - queue->buffer[i].buf.length = buflength; - queue->buffer[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - queue->buffer[i].buf.sequence = 0; - queue->buffer[i].buf.field = V4L2_FIELD_NONE; - queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; - queue->buffer[i].buf.flags = 0; - init_waitqueue_head(&queue->buffer[i].wait); - } - - queue->mem = mem; - queue->count = nbuffers; - queue->buf_size = bufsize; - ret = nbuffers; - -done: - mutex_unlock(&queue->mutex); - return ret; -} - -/* - * Free the video buffers. - * - * This function must be called with the queue lock held. - */ -int uvc_free_buffers(struct uvc_video_queue *queue) -{ - unsigned int i; - - for (i = 0; i < queue->count; ++i) { - if (queue->buffer[i].vma_use_count != 0) - return -EBUSY; - } - - if (queue->count) { - vfree(queue->mem); - queue->count = 0; - } - - return 0; -} - -static void __uvc_query_buffer(struct uvc_buffer *buf, - struct v4l2_buffer *v4l2_buf) -{ - memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf); - - if (buf->vma_use_count) - v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED; - - switch (buf->state) { - case UVC_BUF_STATE_ERROR: - case UVC_BUF_STATE_DONE: - v4l2_buf->flags |= V4L2_BUF_FLAG_DONE; - break; - case UVC_BUF_STATE_QUEUED: - case UVC_BUF_STATE_ACTIVE: - v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; - break; - case UVC_BUF_STATE_IDLE: - default: - break; - } -} - -int uvc_query_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf) -{ - int ret = 0; - - mutex_lock(&queue->mutex); - if (v4l2_buf->index >= queue->count) { - ret = -EINVAL; - goto done; - } - - __uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf); - -done: - mutex_unlock(&queue->mutex); - return ret; -} - -/* - * Queue a video buffer. Attempting to queue a buffer that has already been - * queued will return -EINVAL. - */ -int uvc_queue_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf) -{ - struct uvc_buffer *buf; - unsigned long flags; - int ret = 0; - - uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index); - - if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - v4l2_buf->memory != V4L2_MEMORY_MMAP) { - uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " - "and/or memory (%u).\n", v4l2_buf->type, - v4l2_buf->memory); - return -EINVAL; - } - - mutex_lock(&queue->mutex); - if (v4l2_buf->index >= queue->count) { - uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n"); - ret = -EINVAL; - goto done; - } - - buf = &queue->buffer[v4l2_buf->index]; - if (buf->state != UVC_BUF_STATE_IDLE) { - uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state " - "(%u).\n", buf->state); - ret = -EINVAL; - goto done; - } - - spin_lock_irqsave(&queue->irqlock, flags); - if (queue->flags & UVC_QUEUE_DISCONNECTED) { - spin_unlock_irqrestore(&queue->irqlock, flags); - ret = -ENODEV; - goto done; - } - buf->state = UVC_BUF_STATE_QUEUED; - buf->buf.bytesused = 0; - list_add_tail(&buf->stream, &queue->mainqueue); - list_add_tail(&buf->queue, &queue->irqqueue); - spin_unlock_irqrestore(&queue->irqlock, flags); - -done: - mutex_unlock(&queue->mutex); - return ret; -} - -static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking) -{ - if (nonblocking) { - return (buf->state != UVC_BUF_STATE_QUEUED && - buf->state != UVC_BUF_STATE_ACTIVE) - ? 0 : -EAGAIN; - } - - return wait_event_interruptible(buf->wait, - buf->state != UVC_BUF_STATE_QUEUED && - buf->state != UVC_BUF_STATE_ACTIVE); -} - -/* - * Dequeue a video buffer. If nonblocking is false, block until a buffer is - * available. - */ -int uvc_dequeue_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf, int nonblocking) -{ - struct uvc_buffer *buf; - int ret = 0; - - if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - v4l2_buf->memory != V4L2_MEMORY_MMAP) { - uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) " - "and/or memory (%u).\n", v4l2_buf->type, - v4l2_buf->memory); - return -EINVAL; - } - - mutex_lock(&queue->mutex); - if (list_empty(&queue->mainqueue)) { - uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n"); - ret = -EINVAL; - goto done; - } - - buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); - if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0) - goto done; - - uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n", - buf->buf.index, buf->state, buf->buf.bytesused); - - switch (buf->state) { - case UVC_BUF_STATE_ERROR: - uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data " - "(transmission error).\n"); - ret = -EIO; - case UVC_BUF_STATE_DONE: - buf->state = UVC_BUF_STATE_IDLE; - break; - - case UVC_BUF_STATE_IDLE: - case UVC_BUF_STATE_QUEUED: - case UVC_BUF_STATE_ACTIVE: - default: - uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u " - "(driver bug?).\n", buf->state); - ret = -EINVAL; - goto done; - } - - list_del(&buf->stream); - __uvc_query_buffer(buf, v4l2_buf); - -done: - mutex_unlock(&queue->mutex); - return ret; -} - -/* - * Poll the video queue. - * - * This function implements video queue polling and is intended to be used by - * the device poll handler. - */ -unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, - poll_table *wait) -{ - struct uvc_buffer *buf; - unsigned int mask = 0; - - mutex_lock(&queue->mutex); - if (list_empty(&queue->mainqueue)) { - mask |= POLLERR; - goto done; - } - buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream); - - poll_wait(file, &buf->wait, wait); - if (buf->state == UVC_BUF_STATE_DONE || - buf->state == UVC_BUF_STATE_ERROR) - mask |= POLLIN | POLLRDNORM; - -done: - mutex_unlock(&queue->mutex); - return mask; -} - -/* - * Enable or disable the video buffers queue. - * - * The queue must be enabled before starting video acquisition and must be - * disabled after stopping it. This ensures that the video buffers queue - * state can be properly initialized before buffers are accessed from the - * interrupt handler. - * - * Enabling the video queue initializes parameters (such as sequence number, - * sync pattern, ...). If the queue is already enabled, return -EBUSY. - * - * Disabling the video queue cancels the queue and removes all buffers from - * the main queue. - * - * This function can't be called from interrupt context. Use - * uvc_queue_cancel() instead. - */ -int uvc_queue_enable(struct uvc_video_queue *queue, int enable) -{ - unsigned int i; - int ret = 0; - - mutex_lock(&queue->mutex); - if (enable) { - if (uvc_queue_streaming(queue)) { - ret = -EBUSY; - goto done; - } - queue->sequence = 0; - queue->flags |= UVC_QUEUE_STREAMING; - } else { - uvc_queue_cancel(queue, 0); - INIT_LIST_HEAD(&queue->mainqueue); - - for (i = 0; i < queue->count; ++i) - queue->buffer[i].state = UVC_BUF_STATE_IDLE; - - queue->flags &= ~UVC_QUEUE_STREAMING; - } - -done: - mutex_unlock(&queue->mutex); - return ret; -} - -/* - * Cancel the video buffers queue. - * - * Cancelling the queue marks all buffers on the irq queue as erroneous, - * wakes them up and remove them from the queue. - * - * If the disconnect parameter is set, further calls to uvc_queue_buffer will - * fail with -ENODEV. - * - * This function acquires the irq spinlock and can be called from interrupt - * context. - */ -void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) -{ - struct uvc_buffer *buf; - unsigned long flags; - - spin_lock_irqsave(&queue->irqlock, flags); - while (!list_empty(&queue->irqqueue)) { - buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - list_del(&buf->queue); - buf->state = UVC_BUF_STATE_ERROR; - wake_up(&buf->wait); - } - /* This must be protected by the irqlock spinlock to avoid race - * conditions between uvc_queue_buffer and the disconnection event that - * could result in an interruptible wait in uvc_dequeue_buffer. Do not - * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED - * state outside the queue code. - */ - if (disconnect) - queue->flags |= UVC_QUEUE_DISCONNECTED; - spin_unlock_irqrestore(&queue->irqlock, flags); -} - -struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, - struct uvc_buffer *buf) -{ - struct uvc_buffer *nextbuf; - unsigned long flags; - - if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && - buf->buf.length != buf->buf.bytesused) { - buf->state = UVC_BUF_STATE_QUEUED; - buf->buf.bytesused = 0; - return buf; - } - - spin_lock_irqsave(&queue->irqlock, flags); - list_del(&buf->queue); - if (!list_empty(&queue->irqqueue)) - nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - else - nextbuf = NULL; - spin_unlock_irqrestore(&queue->irqlock, flags); - - buf->buf.sequence = queue->sequence++; - do_gettimeofday(&buf->buf.timestamp); - - wake_up(&buf->wait); - return nextbuf; -} diff --git a/trunk/drivers/media/video/uvc/uvc_status.c b/trunk/drivers/media/video/uvc/uvc_status.c deleted file mode 100644 index be9084e5eace..000000000000 --- a/trunk/drivers/media/video/uvc/uvc_status.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * uvc_status.c -- USB Video Class driver - Status endpoint - * - * Copyright (C) 2007-2008 - * Laurent Pinchart (laurent.pinchart@skynet.be) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include - -#include "uvcvideo.h" - -/* -------------------------------------------------------------------------- - * Input device - */ -static int uvc_input_init(struct uvc_device *dev) -{ - struct usb_device *udev = dev->udev; - struct input_dev *input; - char *phys = NULL; - int ret; - - input = input_allocate_device(); - if (input == NULL) - return -ENOMEM; - - phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath), - GFP_KERNEL); - if (phys == NULL) { - ret = -ENOMEM; - goto error; - } - sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath); - - input->name = dev->name; - input->phys = phys; - usb_to_input_id(udev, &input->id); - input->dev.parent = &dev->intf->dev; - - set_bit(EV_KEY, input->evbit); - set_bit(BTN_0, input->keybit); - - if ((ret = input_register_device(input)) < 0) - goto error; - - dev->input = input; - return 0; - -error: - input_free_device(input); - kfree(phys); - return ret; -} - -static void uvc_input_cleanup(struct uvc_device *dev) -{ - if (dev->input) - input_unregister_device(dev->input); -} - -/* -------------------------------------------------------------------------- - * Status interrupt endpoint - */ -static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) -{ - if (len < 3) { - uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " - "received.\n"); - return; - } - - if (data[2] == 0) { - if (len < 4) - return; - uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", - data[1], data[3] ? "pressed" : "released", len); - if (dev->input) - input_report_key(dev->input, BTN_0, data[3]); - } else { - uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " - "len %d.\n", data[1], data[2], data[3], len); - } -} - -static void uvc_event_control(struct uvc_device *dev, __u8 *data, int len) -{ - char *attrs[3] = { "value", "info", "failure" }; - - if (len < 6 || data[2] != 0 || data[4] > 2) { - uvc_trace(UVC_TRACE_STATUS, "Invalid control status event " - "received.\n"); - return; - } - - uvc_trace(UVC_TRACE_STATUS, "Control %u/%u %s change len %d.\n", - data[1], data[3], attrs[data[4]], len); -} - -static void uvc_status_complete(struct urb *urb) -{ - struct uvc_device *dev = urb->context; - int len, ret; - - switch (urb->status) { - case 0: - break; - - case -ENOENT: /* usb_kill_urb() called. */ - case -ECONNRESET: /* usb_unlink_urb() called. */ - case -ESHUTDOWN: /* The endpoint is being disabled. */ - case -EPROTO: /* Device is disconnected (reported by some - * host controller). */ - return; - - default: - uvc_printk(KERN_WARNING, "Non-zero status (%d) in status " - "completion handler.\n", urb->status); - return; - } - - len = urb->actual_length; - if (len > 0) { - switch (dev->status[0] & 0x0f) { - case UVC_STATUS_TYPE_CONTROL: - uvc_event_control(dev, dev->status, len); - break; - - case UVC_STATUS_TYPE_STREAMING: - uvc_event_streaming(dev, dev->status, len); - break; - - default: - uvc_printk(KERN_INFO, "unknown event type %u.\n", - dev->status[0]); - break; - } - } - - /* Resubmit the URB. */ - urb->interval = dev->int_ep->desc.bInterval; - if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { - uvc_printk(KERN_ERR, "Failed to resubmit status URB (%d).\n", - ret); - } -} - -int uvc_status_init(struct uvc_device *dev) -{ - struct usb_host_endpoint *ep = dev->int_ep; - unsigned int pipe; - int interval; - - if (ep == NULL) - return 0; - - uvc_input_init(dev); - - dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); - if (dev->int_urb == NULL) - return -ENOMEM; - - pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); - - /* For high-speed interrupt endpoints, the bInterval value is used as - * an exponent of two. Some developers forgot about it. - */ - interval = ep->desc.bInterval; - if (interval > 16 && dev->udev->speed == USB_SPEED_HIGH && - (dev->quirks & UVC_QUIRK_STATUS_INTERVAL)) - interval = fls(interval) - 1; - - usb_fill_int_urb(dev->int_urb, dev->udev, pipe, - dev->status, sizeof dev->status, uvc_status_complete, - dev, interval); - - return usb_submit_urb(dev->int_urb, GFP_KERNEL); -} - -void uvc_status_cleanup(struct uvc_device *dev) -{ - usb_kill_urb(dev->int_urb); - usb_free_urb(dev->int_urb); - uvc_input_cleanup(dev); -} - -int uvc_status_suspend(struct uvc_device *dev) -{ - usb_kill_urb(dev->int_urb); - return 0; -} - -int uvc_status_resume(struct uvc_device *dev) -{ - if (dev->int_urb == NULL) - return 0; - - return usb_submit_urb(dev->int_urb, GFP_KERNEL); -} diff --git a/trunk/drivers/media/video/uvc/uvc_v4l2.c b/trunk/drivers/media/video/uvc/uvc_v4l2.c deleted file mode 100644 index 2e0a66575bb4..000000000000 --- a/trunk/drivers/media/video/uvc/uvc_v4l2.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * uvc_v4l2.c -- USB Video Class driver - V4L2 API - * - * Copyright (C) 2005-2008 - * Laurent Pinchart (laurent.pinchart@skynet.be) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "uvcvideo.h" - -/* ------------------------------------------------------------------------ - * V4L2 interface - */ - -/* - * Mapping V4L2 controls to UVC controls can be straighforward if done well. - * Most of the UVC controls exist in V4L2, and can be mapped directly. Some - * must be grouped (for instance the Red Balance, Blue Balance and Do White - * Balance V4L2 controls use the White Balance Component UVC control) or - * otherwise translated. The approach we take here is to use a translation - * table for the controls which can be mapped directly, and handle the others - * manually. - */ -static int uvc_v4l2_query_menu(struct uvc_video_device *video, - struct v4l2_querymenu *query_menu) -{ - struct uvc_menu_info *menu_info; - struct uvc_control_mapping *mapping; - struct uvc_control *ctrl; - - ctrl = uvc_find_control(video, query_menu->id, &mapping); - if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) - return -EINVAL; - - if (query_menu->index >= mapping->menu_count) - return -EINVAL; - - menu_info = &mapping->menu_info[query_menu->index]; - strncpy(query_menu->name, menu_info->name, 32); - return 0; -} - -/* - * Find the frame interval closest to the requested frame interval for the - * given frame format and size. This should be done by the device as part of - * the Video Probe and Commit negotiation, but some hardware don't implement - * that feature. - */ -static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) -{ - unsigned int i; - - if (frame->bFrameIntervalType) { - __u32 best = -1, dist; - - for (i = 0; i < frame->bFrameIntervalType; ++i) { - dist = interval > frame->dwFrameInterval[i] - ? interval - frame->dwFrameInterval[i] - : frame->dwFrameInterval[i] - interval; - - if (dist > best) - break; - - best = dist; - } - - interval = frame->dwFrameInterval[i-1]; - } else { - const __u32 min = frame->dwFrameInterval[0]; - const __u32 max = frame->dwFrameInterval[1]; - const __u32 step = frame->dwFrameInterval[2]; - - interval = min + (interval - min + step/2) / step * step; - if (interval > max) - interval = max; - } - - return interval; -} - -static int uvc_v4l2_try_format(struct uvc_video_device *video, - struct v4l2_format *fmt, struct uvc_streaming_control *probe, - struct uvc_format **uvc_format, struct uvc_frame **uvc_frame) -{ - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; - __u16 rw, rh; - unsigned int d, maxd; - unsigned int i; - __u32 interval; - int ret = 0; - __u8 *fcc; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - fcc = (__u8 *)&fmt->fmt.pix.pixelformat; - uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n", - fmt->fmt.pix.pixelformat, - fcc[0], fcc[1], fcc[2], fcc[3], - fmt->fmt.pix.width, fmt->fmt.pix.height); - - /* Check if the hardware supports the requested format. */ - for (i = 0; i < video->streaming->nformats; ++i) { - format = &video->streaming->format[i]; - if (format->fcc == fmt->fmt.pix.pixelformat) - break; - } - - if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) { - uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n", - fmt->fmt.pix.pixelformat); - return -EINVAL; - } - - /* Find the closest image size. The distance between image sizes is - * the size in pixels of the non-overlapping regions between the - * requested size and the frame-specified size. - */ - rw = fmt->fmt.pix.width; - rh = fmt->fmt.pix.height; - maxd = (unsigned int)-1; - - for (i = 0; i < format->nframes; ++i) { - __u16 w = format->frame[i].wWidth; - __u16 h = format->frame[i].wHeight; - - d = min(w, rw) * min(h, rh); - d = w*h + rw*rh - 2*d; - if (d < maxd) { - maxd = d; - frame = &format->frame[i]; - } - - if (maxd == 0) - break; - } - - if (frame == NULL) { - uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n", - fmt->fmt.pix.width, fmt->fmt.pix.height); - return -EINVAL; - } - - /* Use the default frame interval. */ - interval = frame->dwDefaultFrameInterval; - uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us " - "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval, - (100000000/interval)%10); - - /* Set the format index, frame index and frame interval. */ - memset(probe, 0, sizeof *probe); - probe->bmHint = 1; /* dwFrameInterval */ - probe->bFormatIndex = format->index; - probe->bFrameIndex = frame->bFrameIndex; - probe->dwFrameInterval = uvc_try_frame_interval(frame, interval); - /* Some webcams stall the probe control set request when the - * dwMaxVideoFrameSize field is set to zero. The UVC specification - * clearly states that the field is read-only from the host, so this - * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by - * the webcam to work around the problem. - * - * The workaround could probably be enabled for all webcams, so the - * quirk can be removed if needed. It's currently useful to detect - * webcam bugs and fix them before they hit the market (providing - * developers test their webcams with the Linux driver as well as with - * the Windows driver). - */ - if (video->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) - probe->dwMaxVideoFrameSize = - video->streaming->ctrl.dwMaxVideoFrameSize; - - /* Probe the device */ - if ((ret = uvc_probe_video(video, probe)) < 0) - goto done; - - fmt->fmt.pix.width = frame->wWidth; - fmt->fmt.pix.height = frame->wHeight; - fmt->fmt.pix.field = V4L2_FIELD_NONE; - fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; - fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize; - fmt->fmt.pix.colorspace = format->colorspace; - fmt->fmt.pix.priv = 0; - - if (uvc_format != NULL) - *uvc_format = format; - if (uvc_frame != NULL) - *uvc_frame = frame; - -done: - return ret; -} - -static int uvc_v4l2_get_format(struct uvc_video_device *video, - struct v4l2_format *fmt) -{ - struct uvc_format *format = video->streaming->cur_format; - struct uvc_frame *frame = video->streaming->cur_frame; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (format == NULL || frame == NULL) - return -EINVAL; - - fmt->fmt.pix.pixelformat = format->fcc; - fmt->fmt.pix.width = frame->wWidth; - fmt->fmt.pix.height = frame->wHeight; - fmt->fmt.pix.field = V4L2_FIELD_NONE; - fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; - fmt->fmt.pix.sizeimage = video->streaming->ctrl.dwMaxVideoFrameSize; - fmt->fmt.pix.colorspace = format->colorspace; - fmt->fmt.pix.priv = 0; - - return 0; -} - -static int uvc_v4l2_set_format(struct uvc_video_device *video, - struct v4l2_format *fmt) -{ - struct uvc_streaming_control probe; - struct uvc_format *format; - struct uvc_frame *frame; - int ret; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (uvc_queue_streaming(&video->queue)) - return -EBUSY; - - ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); - if (ret < 0) - return ret; - - if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) - return ret; - - memcpy(&video->streaming->ctrl, &probe, sizeof probe); - video->streaming->cur_format = format; - video->streaming->cur_frame = frame; - - return 0; -} - -static int uvc_v4l2_get_streamparm(struct uvc_video_device *video, - struct v4l2_streamparm *parm) -{ - uint32_t numerator, denominator; - - if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - numerator = video->streaming->ctrl.dwFrameInterval; - denominator = 10000000; - uvc_simplify_fraction(&numerator, &denominator, 8, 333); - - memset(parm, 0, sizeof *parm); - parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; - parm->parm.capture.capturemode = 0; - parm->parm.capture.timeperframe.numerator = numerator; - parm->parm.capture.timeperframe.denominator = denominator; - parm->parm.capture.extendedmode = 0; - parm->parm.capture.readbuffers = 0; - - return 0; -} - -static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, - struct v4l2_streamparm *parm) -{ - struct uvc_frame *frame = video->streaming->cur_frame; - struct uvc_streaming_control probe; - uint32_t interval; - int ret; - - if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (uvc_queue_streaming(&video->queue)) - return -EBUSY; - - memcpy(&probe, &video->streaming->ctrl, sizeof probe); - interval = uvc_fraction_to_interval( - parm->parm.capture.timeperframe.numerator, - parm->parm.capture.timeperframe.denominator); - - uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", - parm->parm.capture.timeperframe.numerator, - parm->parm.capture.timeperframe.denominator, - interval); - probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); - - /* Probe the device with the new settings. */ - if ((ret = uvc_probe_video(video, &probe)) < 0) - return ret; - - /* Commit the new settings. */ - if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) - return ret; - - memcpy(&video->streaming->ctrl, &probe, sizeof probe); - - /* Return the actual frame period. */ - parm->parm.capture.timeperframe.numerator = probe.dwFrameInterval; - parm->parm.capture.timeperframe.denominator = 10000000; - uvc_simplify_fraction(&parm->parm.capture.timeperframe.numerator, - &parm->parm.capture.timeperframe.denominator, - 8, 333); - - return 0; -} - -/* ------------------------------------------------------------------------ - * Privilege management - */ - -/* - * Privilege management is the multiple-open implementation basis. The current - * implementation is completely transparent for the end-user and doesn't - * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls. - * Those ioctls enable finer control on the device (by making possible for a - * user to request exclusive access to a device), but are not mature yet. - * Switching to the V4L2 priority mechanism might be considered in the future - * if this situation changes. - * - * Each open instance of a UVC device can either be in a privileged or - * unprivileged state. Only a single instance can be in a privileged state at - * a given time. Trying to perform an operation which requires privileges will - * automatically acquire the required privileges if possible, or return -EBUSY - * otherwise. Privileges are dismissed when closing the instance. - * - * Operations which require privileges are: - * - * - VIDIOC_S_INPUT - * - VIDIOC_S_PARM - * - VIDIOC_S_FMT - * - VIDIOC_TRY_FMT - * - VIDIOC_REQBUFS - */ -static int uvc_acquire_privileges(struct uvc_fh *handle) -{ - int ret = 0; - - /* Always succeed if the handle is already privileged. */ - if (handle->state == UVC_HANDLE_ACTIVE) - return 0; - - /* Check if the device already has a privileged handle. */ - mutex_lock(&uvc_driver.open_mutex); - if (atomic_inc_return(&handle->device->active) != 1) { - atomic_dec(&handle->device->active); - ret = -EBUSY; - goto done; - } - - handle->state = UVC_HANDLE_ACTIVE; - -done: - mutex_unlock(&uvc_driver.open_mutex); - return ret; -} - -static void uvc_dismiss_privileges(struct uvc_fh *handle) -{ - if (handle->state == UVC_HANDLE_ACTIVE) - atomic_dec(&handle->device->active); - - handle->state = UVC_HANDLE_PASSIVE; -} - -static int uvc_has_privileges(struct uvc_fh *handle) -{ - return handle->state == UVC_HANDLE_ACTIVE; -} - -/* ------------------------------------------------------------------------ - * V4L2 file operations - */ - -static int uvc_v4l2_open(struct inode *inode, struct file *file) -{ - struct video_device *vdev; - struct uvc_video_device *video; - struct uvc_fh *handle; - int ret = 0; - - uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); - mutex_lock(&uvc_driver.open_mutex); - vdev = video_devdata(file); - video = video_get_drvdata(vdev); - - if (video->dev->state & UVC_DEV_DISCONNECTED) { - ret = -ENODEV; - goto done; - } - - ret = usb_autopm_get_interface(video->dev->intf); - if (ret < 0) - goto done; - - /* Create the device handle. */ - handle = kzalloc(sizeof *handle, GFP_KERNEL); - if (handle == NULL) { - usb_autopm_put_interface(video->dev->intf); - ret = -ENOMEM; - goto done; - } - - handle->device = video; - handle->state = UVC_HANDLE_PASSIVE; - file->private_data = handle; - - kref_get(&video->dev->kref); - -done: - mutex_unlock(&uvc_driver.open_mutex); - return ret; -} - -static int uvc_v4l2_release(struct inode *inode, struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct uvc_video_device *video = video_get_drvdata(vdev); - struct uvc_fh *handle = (struct uvc_fh *)file->private_data; - - uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); - - /* Only free resources if this is a privileged handle. */ - if (uvc_has_privileges(handle)) { - uvc_video_enable(video, 0); - - mutex_lock(&video->queue.mutex); - if (uvc_free_buffers(&video->queue) < 0) - uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " - "free buffers.\n"); - mutex_unlock(&video->queue.mutex); - } - - /* Release the file handle. */ - uvc_dismiss_privileges(handle); - kfree(handle); - file->private_data = NULL; - - usb_autopm_put_interface(video->dev->intf); - kref_put(&video->dev->kref, uvc_delete); - return 0; -} - -static int uvc_v4l2_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *vdev = video_devdata(file); - struct uvc_video_device *video = video_get_drvdata(vdev); - struct uvc_fh *handle = (struct uvc_fh *)file->private_data; - int ret = 0; - - if (uvc_trace_param & UVC_TRACE_IOCTL) - v4l_printk_ioctl(cmd); - - switch (cmd) { - /* Query capabilities */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap, 0, sizeof *cap); - strncpy(cap->driver, "uvcvideo", sizeof cap->driver); - strncpy(cap->card, vdev->name, 32); - strncpy(cap->bus_info, video->dev->udev->bus->bus_name, - sizeof cap->bus_info); - cap->version = DRIVER_VERSION_NUMBER; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE - | V4L2_CAP_STREAMING; - break; - } - - /* Get, Set & Query control */ - case VIDIOC_QUERYCTRL: - return uvc_query_v4l2_ctrl(video, arg); - - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_ext_control xctrl; - - memset(&xctrl, 0, sizeof xctrl); - xctrl.id = ctrl->id; - - uvc_ctrl_begin(video); - ret = uvc_ctrl_get(video, &xctrl); - uvc_ctrl_rollback(video); - if (ret >= 0) - ctrl->value = xctrl.value; - break; - } - - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_ext_control xctrl; - - memset(&xctrl, 0, sizeof xctrl); - xctrl.id = ctrl->id; - xctrl.value = ctrl->value; - - uvc_ctrl_begin(video); - ret = uvc_ctrl_set(video, &xctrl); - if (ret < 0) { - uvc_ctrl_rollback(video); - return ret; - } - ret = uvc_ctrl_commit(video); - break; - } - - case VIDIOC_QUERYMENU: - return uvc_v4l2_query_menu(video, arg); - - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *ctrls = arg; - struct v4l2_ext_control *ctrl = ctrls->controls; - unsigned int i; - - uvc_ctrl_begin(video); - for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_get(video, ctrl); - if (ret < 0) { - uvc_ctrl_rollback(video); - ctrls->error_idx = i; - return ret; - } - } - ctrls->error_idx = 0; - ret = uvc_ctrl_rollback(video); - break; - } - - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *ctrls = arg; - struct v4l2_ext_control *ctrl = ctrls->controls; - unsigned int i; - - ret = uvc_ctrl_begin(video); - if (ret < 0) - return ret; - - for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_set(video, ctrl); - if (ret < 0) { - uvc_ctrl_rollback(video); - ctrls->error_idx = i; - return ret; - } - } - - ctrls->error_idx = 0; - - if (cmd == VIDIOC_S_EXT_CTRLS) - ret = uvc_ctrl_commit(video); - else - ret = uvc_ctrl_rollback(video); - break; - } - - /* Get, Set & Enum input */ - case VIDIOC_ENUMINPUT: - { - const struct uvc_entity *selector = video->selector; - struct v4l2_input *input = arg; - struct uvc_entity *iterm = NULL; - u32 index = input->index; - int pin = 0; - - if (selector == NULL || - (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - if (index != 0) - return -EINVAL; - iterm = list_first_entry(&video->iterms, - struct uvc_entity, chain); - pin = iterm->id; - } else if (pin < selector->selector.bNrInPins) { - pin = selector->selector.baSourceID[index]; - list_for_each_entry(iterm, video->iterms.next, chain) { - if (iterm->id == pin) - break; - } - } - - if (iterm == NULL || iterm->id != pin) - return -EINVAL; - - memset(input, 0, sizeof *input); - input->index = index; - strncpy(input->name, iterm->name, sizeof input->name); - if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA) - input->type = V4L2_INPUT_TYPE_CAMERA; - break; - } - - case VIDIOC_G_INPUT: - { - u8 input; - - if (video->selector == NULL || - (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - *(int *)arg = 0; - break; - } - - ret = uvc_query_ctrl(video->dev, GET_CUR, video->selector->id, - video->dev->intfnum, SU_INPUT_SELECT_CONTROL, - &input, 1); - if (ret < 0) - return ret; - - *(int *)arg = input - 1; - break; - } - - case VIDIOC_S_INPUT: - { - u8 input = *(u32 *)arg + 1; - - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; - - if (video->selector == NULL || - (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - if (input != 1) - return -EINVAL; - break; - } - - if (input > video->selector->selector.bNrInPins) - return -EINVAL; - - return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, - video->dev->intfnum, SU_INPUT_SELECT_CONTROL, - &input, 1); - } - - /* Try, Get, Set & Enum format */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmt = arg; - struct uvc_format *format; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fmt->index >= video->streaming->nformats) - return -EINVAL; - - format = &video->streaming->format[fmt->index]; - fmt->flags = 0; - if (format->flags & UVC_FMT_FLAG_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; - strncpy(fmt->description, format->name, - sizeof fmt->description); - fmt->description[sizeof fmt->description - 1] = 0; - fmt->pixelformat = format->fcc; - break; - } - - case VIDIOC_TRY_FMT: - { - struct uvc_streaming_control probe; - - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; - - return uvc_v4l2_try_format(video, arg, &probe, NULL, NULL); - } - - case VIDIOC_S_FMT: - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; - - return uvc_v4l2_set_format(video, arg); - - case VIDIOC_G_FMT: - return uvc_v4l2_get_format(video, arg); - - /* Frame size enumeration */ - case VIDIOC_ENUM_FRAMESIZES: - { - struct v4l2_frmsizeenum *fsize = arg; - struct uvc_format *format = NULL; - struct uvc_frame *frame; - int i; - - /* Look for the given pixel format */ - for (i = 0; i < video->streaming->nformats; i++) { - if (video->streaming->format[i].fcc == - fsize->pixel_format) { - format = &video->streaming->format[i]; - break; - } - } - if (format == NULL) - return -EINVAL; - - if (fsize->index >= format->nframes) - return -EINVAL; - - frame = &format->frame[fsize->index]; - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = frame->wWidth; - fsize->discrete.height = frame->wHeight; - break; - } - - /* Frame interval enumeration */ - case VIDIOC_ENUM_FRAMEINTERVALS: - { - struct v4l2_frmivalenum *fival = arg; - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; - int i; - - /* Look for the given pixel format and frame size */ - for (i = 0; i < video->streaming->nformats; i++) { - if (video->streaming->format[i].fcc == - fival->pixel_format) { - format = &video->streaming->format[i]; - break; - } - } - if (format == NULL) - return -EINVAL; - - for (i = 0; i < format->nframes; i++) { - if (format->frame[i].wWidth == fival->width && - format->frame[i].wHeight == fival->height) { - frame = &format->frame[i]; - break; - } - } - if (frame == NULL) - return -EINVAL; - - if (frame->bFrameIntervalType) { - if (fival->index >= frame->bFrameIntervalType) - return -EINVAL; - - fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; - fival->discrete.numerator = - frame->dwFrameInterval[fival->index]; - fival->discrete.denominator = 10000000; - uvc_simplify_fraction(&fival->discrete.numerator, - &fival->discrete.denominator, 8, 333); - } else { - fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; - fival->stepwise.min.numerator = - frame->dwFrameInterval[0]; - fival->stepwise.min.denominator = 10000000; - fival->stepwise.max.numerator = - frame->dwFrameInterval[1]; - fival->stepwise.max.denominator = 10000000; - fival->stepwise.step.numerator = - frame->dwFrameInterval[2]; - fival->stepwise.step.denominator = 10000000; - uvc_simplify_fraction(&fival->stepwise.min.numerator, - &fival->stepwise.min.denominator, 8, 333); - uvc_simplify_fraction(&fival->stepwise.max.numerator, - &fival->stepwise.max.denominator, 8, 333); - uvc_simplify_fraction(&fival->stepwise.step.numerator, - &fival->stepwise.step.denominator, 8, 333); - } - break; - } - - /* Get & Set streaming parameters */ - case VIDIOC_G_PARM: - return uvc_v4l2_get_streamparm(video, arg); - - case VIDIOC_S_PARM: - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; - - return uvc_v4l2_set_streamparm(video, arg); - - /* Cropping and scaling */ - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *ccap = arg; - struct uvc_frame *frame = video->streaming->cur_frame; - - if (ccap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - ccap->bounds.left = 0; - ccap->bounds.top = 0; - ccap->bounds.width = frame->wWidth; - ccap->bounds.height = frame->wHeight; - - ccap->defrect = ccap->bounds; - - ccap->pixelaspect.numerator = 1; - ccap->pixelaspect.denominator = 1; - break; - } - - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - return -EINVAL; - - /* Buffers & streaming */ - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *rb = arg; - unsigned int bufsize = - video->streaming->ctrl.dwMaxVideoFrameSize; - - if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - rb->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; - - ret = uvc_alloc_buffers(&video->queue, rb->count, bufsize); - if (ret < 0) - return ret; - - if (!(video->streaming->cur_format->flags & - UVC_FMT_FLAG_COMPRESSED)) - video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE; - - rb->count = ret; - ret = 0; - break; - } - - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; - - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (!uvc_has_privileges(handle)) - return -EBUSY; - - return uvc_query_buffer(&video->queue, buf); - } - - case VIDIOC_QBUF: - if (!uvc_has_privileges(handle)) - return -EBUSY; - - return uvc_queue_buffer(&video->queue, arg); - - case VIDIOC_DQBUF: - if (!uvc_has_privileges(handle)) - return -EBUSY; - - return uvc_dequeue_buffer(&video->queue, arg, - file->f_flags & O_NONBLOCK); - - case VIDIOC_STREAMON: - { - int *type = arg; - - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (!uvc_has_privileges(handle)) - return -EBUSY; - - if ((ret = uvc_video_enable(video, 1)) < 0) - return ret; - break; - } - - case VIDIOC_STREAMOFF: - { - int *type = arg; - - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (!uvc_has_privileges(handle)) - return -EBUSY; - - return uvc_video_enable(video, 0); - } - - /* Analog video standards make no sense for digital cameras. */ - case VIDIOC_ENUMSTD: - case VIDIOC_QUERYSTD: - case VIDIOC_G_STD: - case VIDIOC_S_STD: - - case VIDIOC_OVERLAY: - - case VIDIOC_ENUMAUDIO: - case VIDIOC_ENUMAUDOUT: - - case VIDIOC_ENUMOUTPUT: - uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); - return -EINVAL; - - /* Dynamic controls. */ - case UVCIOC_CTRL_ADD: - { - struct uvc_xu_control_info *xinfo = arg; - struct uvc_control_info *info; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - info = kmalloc(sizeof *info, GFP_KERNEL); - if (info == NULL) - return -ENOMEM; - - memcpy(info->entity, xinfo->entity, sizeof info->entity); - info->index = xinfo->index; - info->selector = xinfo->selector; - info->size = xinfo->size; - info->flags = xinfo->flags; - - info->flags |= UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | - UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF; - - ret = uvc_ctrl_add_info(info); - if (ret < 0) - kfree(info); - break; - } - - case UVCIOC_CTRL_MAP: - { - struct uvc_xu_control_mapping *xmap = arg; - struct uvc_control_mapping *map; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - map = kmalloc(sizeof *map, GFP_KERNEL); - if (map == NULL) - return -ENOMEM; - - map->id = xmap->id; - memcpy(map->name, xmap->name, sizeof map->name); - memcpy(map->entity, xmap->entity, sizeof map->entity); - map->selector = xmap->selector; - map->size = xmap->size; - map->offset = xmap->offset; - map->v4l2_type = xmap->v4l2_type; - map->data_type = xmap->data_type; - - ret = uvc_ctrl_add_mapping(map); - if (ret < 0) - kfree(map); - break; - } - - case UVCIOC_CTRL_GET: - return uvc_xu_ctrl_query(video, arg, 0); - - case UVCIOC_CTRL_SET: - return uvc_xu_ctrl_query(video, arg, 1); - - default: - if ((ret = v4l_compat_translate_ioctl(inode, file, cmd, arg, - uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD) - uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", - cmd); - return ret; - } - - return ret; -} - -static int uvc_v4l2_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_ioctl\n"); - return video_usercopy(inode, file, cmd, arg, uvc_v4l2_do_ioctl); -} - -static ssize_t uvc_v4l2_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n"); - return -ENODEV; -} - -/* - * VMA operations. - */ -static void uvc_vm_open(struct vm_area_struct *vma) -{ - struct uvc_buffer *buffer = vma->vm_private_data; - buffer->vma_use_count++; -} - -static void uvc_vm_close(struct vm_area_struct *vma) -{ - struct uvc_buffer *buffer = vma->vm_private_data; - buffer->vma_use_count--; -} - -static struct vm_operations_struct uvc_vm_ops = { - .open = uvc_vm_open, - .close = uvc_vm_close, -}; - -static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct video_device *vdev = video_devdata(file); - struct uvc_video_device *video = video_get_drvdata(vdev); - struct uvc_buffer *buffer; - struct page *page; - unsigned long addr, start, size; - unsigned int i; - int ret = 0; - - uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); - - start = vma->vm_start; - size = vma->vm_end - vma->vm_start; - - mutex_lock(&video->queue.mutex); - - for (i = 0; i < video->queue.count; ++i) { - buffer = &video->queue.buffer[i]; - if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) - break; - } - - if (i == video->queue.count || size != video->queue.buf_size) { - ret = -EINVAL; - goto done; - } - - /* - * VM_IO marks the area as being an mmaped region for I/O to a - * device. It also prevents the region from being core dumped. - */ - vma->vm_flags |= VM_IO; - - addr = (unsigned long)video->queue.mem + buffer->buf.m.offset; - while (size > 0) { - page = vmalloc_to_page((void *)addr); - if ((ret = vm_insert_page(vma, start, page)) < 0) - goto done; - - start += PAGE_SIZE; - addr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vma->vm_ops = &uvc_vm_ops; - vma->vm_private_data = buffer; - uvc_vm_open(vma); - -done: - mutex_unlock(&video->queue.mutex); - return ret; -} - -static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) -{ - struct video_device *vdev = video_devdata(file); - struct uvc_video_device *video = video_get_drvdata(vdev); - - uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n"); - - return uvc_queue_poll(&video->queue, file, wait); -} - -struct file_operations uvc_fops = { - .owner = THIS_MODULE, - .open = uvc_v4l2_open, - .release = uvc_v4l2_release, - .ioctl = uvc_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, - .read = uvc_v4l2_read, - .mmap = uvc_v4l2_mmap, - .poll = uvc_v4l2_poll, -}; diff --git a/trunk/drivers/media/video/uvc/uvc_video.c b/trunk/drivers/media/video/uvc/uvc_video.c deleted file mode 100644 index 6faf1fb21614..000000000000 --- a/trunk/drivers/media/video/uvc/uvc_video.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - * uvc_video.c -- USB Video Class driver - Video handling - * - * Copyright (C) 2005-2008 - * Laurent Pinchart (laurent.pinchart@skynet.be) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "uvcvideo.h" - -/* ------------------------------------------------------------------------ - * UVC Controls - */ - -static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, - __u8 intfnum, __u8 cs, void *data, __u16 size, - int timeout) -{ - __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; - unsigned int pipe; - int ret; - - pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) - : usb_sndctrlpipe(dev->udev, 0); - type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT; - - ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8, - unit << 8 | intfnum, data, size, timeout); - - if (ret != size) { - uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u " - "(unit %u) : %d (exp. %u).\n", query, cs, unit, ret, - size); - return -EIO; - } - - return 0; -} - -int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, - __u8 intfnum, __u8 cs, void *data, __u16 size) -{ - return __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size, - UVC_CTRL_CONTROL_TIMEOUT); -} - -static void uvc_fixup_buffer_size(struct uvc_video_device *video, - struct uvc_streaming_control *ctrl) -{ - struct uvc_format *format; - struct uvc_frame *frame; - - if (ctrl->bFormatIndex <= 0 || - ctrl->bFormatIndex > video->streaming->nformats) - return; - - format = &video->streaming->format[ctrl->bFormatIndex - 1]; - - if (ctrl->bFrameIndex <= 0 || - ctrl->bFrameIndex > format->nframes) - return; - - frame = &format->frame[ctrl->bFrameIndex - 1]; - - if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || - (ctrl->dwMaxVideoFrameSize == 0 && - video->dev->uvc_version < 0x0110)) - ctrl->dwMaxVideoFrameSize = - frame->dwMaxVideoFrameBufferSize; -} - -static int uvc_get_video_ctrl(struct uvc_video_device *video, - struct uvc_streaming_control *ctrl, int probe, __u8 query) -{ - __u8 data[34]; - __u8 size; - int ret; - - size = video->dev->uvc_version >= 0x0110 ? 34 : 26; - ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, - probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, - UVC_CTRL_STREAMING_TIMEOUT); - - if (ret < 0) - return ret; - - ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]); - ctrl->bFormatIndex = data[2]; - ctrl->bFrameIndex = data[3]; - ctrl->dwFrameInterval = le32_to_cpup((__le32 *)&data[4]); - ctrl->wKeyFrameRate = le16_to_cpup((__le16 *)&data[8]); - ctrl->wPFrameRate = le16_to_cpup((__le16 *)&data[10]); - ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]); - ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]); - ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]); - ctrl->dwMaxVideoFrameSize = - le32_to_cpu(get_unaligned((__le32 *)&data[18])); - ctrl->dwMaxPayloadTransferSize = - le32_to_cpu(get_unaligned((__le32 *)&data[22])); - - if (size == 34) { - ctrl->dwClockFrequency = - le32_to_cpu(get_unaligned((__le32 *)&data[26])); - ctrl->bmFramingInfo = data[30]; - ctrl->bPreferedVersion = data[31]; - ctrl->bMinVersion = data[32]; - ctrl->bMaxVersion = data[33]; - } else { - ctrl->dwClockFrequency = video->dev->clock_frequency; - ctrl->bmFramingInfo = 0; - ctrl->bPreferedVersion = 0; - ctrl->bMinVersion = 0; - ctrl->bMaxVersion = 0; - } - - /* Some broken devices return a null or wrong dwMaxVideoFrameSize. - * Try to get the value from the format and frame descriptor. - */ - uvc_fixup_buffer_size(video, ctrl); - - return 0; -} - -int uvc_set_video_ctrl(struct uvc_video_device *video, - struct uvc_streaming_control *ctrl, int probe) -{ - __u8 data[34]; - __u8 size; - - size = video->dev->uvc_version >= 0x0110 ? 34 : 26; - memset(data, 0, sizeof data); - - *(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint); - data[2] = ctrl->bFormatIndex; - data[3] = ctrl->bFrameIndex; - *(__le32 *)&data[4] = cpu_to_le32(ctrl->dwFrameInterval); - *(__le16 *)&data[8] = cpu_to_le16(ctrl->wKeyFrameRate); - *(__le16 *)&data[10] = cpu_to_le16(ctrl->wPFrameRate); - *(__le16 *)&data[12] = cpu_to_le16(ctrl->wCompQuality); - *(__le16 *)&data[14] = cpu_to_le16(ctrl->wCompWindowSize); - *(__le16 *)&data[16] = cpu_to_le16(ctrl->wDelay); - /* Note: Some of the fields below are not required for IN devices (see - * UVC spec, 4.3.1.1), but we still copy them in case support for OUT - * devices is added in the future. */ - put_unaligned(cpu_to_le32(ctrl->dwMaxVideoFrameSize), - (__le32 *)&data[18]); - put_unaligned(cpu_to_le32(ctrl->dwMaxPayloadTransferSize), - (__le32 *)&data[22]); - - if (size == 34) { - put_unaligned(cpu_to_le32(ctrl->dwClockFrequency), - (__le32 *)&data[26]); - data[30] = ctrl->bmFramingInfo; - data[31] = ctrl->bPreferedVersion; - data[32] = ctrl->bMinVersion; - data[33] = ctrl->bMaxVersion; - } - - return __uvc_query_ctrl(video->dev, SET_CUR, 0, - video->streaming->intfnum, - probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size, - UVC_CTRL_STREAMING_TIMEOUT); -} - -int uvc_probe_video(struct uvc_video_device *video, - struct uvc_streaming_control *probe) -{ - struct uvc_streaming_control probe_min, probe_max; - __u16 bandwidth; - unsigned int i; - int ret; - - mutex_lock(&video->streaming->mutex); - - /* Perform probing. The device should adjust the requested values - * according to its capabilities. However, some devices, namely the - * first generation UVC Logitech webcams, don't implement the Video - * Probe control properly, and just return the needed bandwidth. For - * that reason, if the needed bandwidth exceeds the maximum available - * bandwidth, try to lower the quality. - */ - if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0) - goto done; - - /* Get the minimum and maximum values for compression settings. */ - if (!(video->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) { - ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN); - if (ret < 0) - goto done; - ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX); - if (ret < 0) - goto done; - - probe->wCompQuality = probe_max.wCompQuality; - } - - for (i = 0; i < 2; ++i) { - if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0 || - (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) - goto done; - - if (video->streaming->intf->num_altsetting == 1) - break; - - bandwidth = probe->dwMaxPayloadTransferSize; - if (bandwidth <= video->streaming->maxpsize) - break; - - if (video->dev->quirks & UVC_QUIRK_PROBE_MINMAX) { - ret = -ENOSPC; - goto done; - } - - /* TODO: negotiate compression parameters */ - probe->wKeyFrameRate = probe_min.wKeyFrameRate; - probe->wPFrameRate = probe_min.wPFrameRate; - probe->wCompQuality = probe_max.wCompQuality; - probe->wCompWindowSize = probe_min.wCompWindowSize; - } - -done: - mutex_unlock(&video->streaming->mutex); - return ret; -} - -/* ------------------------------------------------------------------------ - * Video codecs - */ - -/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ -#define UVC_STREAM_EOH (1 << 7) -#define UVC_STREAM_ERR (1 << 6) -#define UVC_STREAM_STI (1 << 5) -#define UVC_STREAM_RES (1 << 4) -#define UVC_STREAM_SCR (1 << 3) -#define UVC_STREAM_PTS (1 << 2) -#define UVC_STREAM_EOF (1 << 1) -#define UVC_STREAM_FID (1 << 0) - -/* Video payload decoding is handled by uvc_video_decode_start(), - * uvc_video_decode_data() and uvc_video_decode_end(). - * - * uvc_video_decode_start is called with URB data at the start of a bulk or - * isochronous payload. It processes header data and returns the header size - * in bytes if successful. If an error occurs, it returns a negative error - * code. The following error codes have special meanings. - * - * - EAGAIN informs the caller that the current video buffer should be marked - * as done, and that the function should be called again with the same data - * and a new video buffer. This is used when end of frame conditions can be - * reliably detected at the beginning of the next frame only. - * - * If an error other than -EAGAIN is returned, the caller will drop the current - * payload. No call to uvc_video_decode_data and uvc_video_decode_end will be - * made until the next payload. -ENODATA can be used to drop the current - * payload if no other error code is appropriate. - * - * uvc_video_decode_data is called for every URB with URB data. It copies the - * data to the video buffer. - * - * uvc_video_decode_end is called with header data at the end of a bulk or - * isochronous payload. It performs any additional header data processing and - * returns 0 or a negative error code if an error occured. As header data have - * already been processed by uvc_video_decode_start, this functions isn't - * required to perform sanity checks a second time. - * - * For isochronous transfers where a payload is always transfered in a single - * URB, the three functions will be called in a row. - * - * To let the decoder process header data and update its internal state even - * when no video buffer is available, uvc_video_decode_start must be prepared - * to be called with a NULL buf parameter. uvc_video_decode_data and - * uvc_video_decode_end will never be called with a NULL buffer. - */ -static int uvc_video_decode_start(struct uvc_video_device *video, - struct uvc_buffer *buf, const __u8 *data, int len) -{ - __u8 fid; - - /* Sanity checks: - * - packet must be at least 2 bytes long - * - bHeaderLength value must be at least 2 bytes (see above) - * - bHeaderLength value can't be larger than the packet size. - */ - if (len < 2 || data[0] < 2 || data[0] > len) - return -EINVAL; - - /* Skip payloads marked with the error bit ("error frames"). */ - if (data[1] & UVC_STREAM_ERR) { - uvc_trace(UVC_TRACE_FRAME, "Dropping payload (error bit " - "set).\n"); - return -ENODATA; - } - - fid = data[1] & UVC_STREAM_FID; - - /* Store the payload FID bit and return immediately when the buffer is - * NULL. - */ - if (buf == NULL) { - video->last_fid = fid; - return -ENODATA; - } - - /* Synchronize to the input stream by waiting for the FID bit to be - * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. - * queue->last_fid is initialized to -1, so the first isochronous - * frame will always be in sync. - * - * If the device doesn't toggle the FID bit, invert video->last_fid - * when the EOF bit is set to force synchronisation on the next packet. - */ - if (buf->state != UVC_BUF_STATE_ACTIVE) { - if (fid == video->last_fid) { - uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of " - "sync).\n"); - if ((video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) && - (data[1] & UVC_STREAM_EOF)) - video->last_fid ^= UVC_STREAM_FID; - return -ENODATA; - } - - /* TODO: Handle PTS and SCR. */ - buf->state = UVC_BUF_STATE_ACTIVE; - } - - /* Mark the buffer as done if we're at the beginning of a new frame. - * End of frame detection is better implemented by checking the EOF - * bit (FID bit toggling is delayed by one frame compared to the EOF - * bit), but some devices don't set the bit at end of frame (and the - * last payload can be lost anyway). We thus must check if the FID has - * been toggled. - * - * queue->last_fid is initialized to -1, so the first isochronous - * frame will never trigger an end of frame detection. - * - * Empty buffers (bytesused == 0) don't trigger end of frame detection - * as it doesn't make sense to return an empty buffer. This also - * avoids detecting and of frame conditions at FID toggling if the - * previous payload had the EOF bit set. - */ - if (fid != video->last_fid && buf->buf.bytesused != 0) { - uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " - "toggled).\n"); - buf->state = UVC_BUF_STATE_DONE; - return -EAGAIN; - } - - video->last_fid = fid; - - return data[0]; -} - -static void uvc_video_decode_data(struct uvc_video_device *video, - struct uvc_buffer *buf, const __u8 *data, int len) -{ - struct uvc_video_queue *queue = &video->queue; - unsigned int maxlen, nbytes; - void *mem; - - if (len <= 0) - return; - - /* Copy the video data to the buffer. */ - maxlen = buf->buf.length - buf->buf.bytesused; - mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused; - nbytes = min((unsigned int)len, maxlen); - memcpy(mem, data, nbytes); - buf->buf.bytesused += nbytes; - - /* Complete the current frame if the buffer size was exceeded. */ - if (len > maxlen) { - uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n"); - buf->state = UVC_BUF_STATE_DONE; - } -} - -static void uvc_video_decode_end(struct uvc_video_device *video, - struct uvc_buffer *buf, const __u8 *data, int len) -{ - /* Mark the buffer as done if the EOF marker is set. */ - if (data[1] & UVC_STREAM_EOF && buf->buf.bytesused != 0) { - uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); - if (data[0] == len) - uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); - buf->state = UVC_BUF_STATE_DONE; - if (video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) - video->last_fid ^= UVC_STREAM_FID; - } -} - -/* ------------------------------------------------------------------------ - * URB handling - */ - -/* - * Completion handler for video URBs. - */ -static void uvc_video_decode_isoc(struct urb *urb, - struct uvc_video_device *video, struct uvc_buffer *buf) -{ - u8 *mem; - int ret, i; - - for (i = 0; i < urb->number_of_packets; ++i) { - if (urb->iso_frame_desc[i].status < 0) { - uvc_trace(UVC_TRACE_FRAME, "USB isochronous frame " - "lost (%d).\n", urb->iso_frame_desc[i].status); - continue; - } - - /* Decode the payload header. */ - mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset; - do { - ret = uvc_video_decode_start(video, buf, mem, - urb->iso_frame_desc[i].actual_length); - if (ret == -EAGAIN) - buf = uvc_queue_next_buffer(&video->queue, buf); - } while (ret == -EAGAIN); - - if (ret < 0) - continue; - - /* Decode the payload data. */ - uvc_video_decode_data(video, buf, mem + ret, - urb->iso_frame_desc[i].actual_length - ret); - - /* Process the header again. */ - uvc_video_decode_end(video, buf, mem, ret); - - if (buf->state == UVC_BUF_STATE_DONE || - buf->state == UVC_BUF_STATE_ERROR) - buf = uvc_queue_next_buffer(&video->queue, buf); - } -} - -static void uvc_video_decode_bulk(struct urb *urb, - struct uvc_video_device *video, struct uvc_buffer *buf) -{ - u8 *mem; - int len, ret; - - mem = urb->transfer_buffer; - len = urb->actual_length; - video->bulk.payload_size += len; - - /* If the URB is the first of its payload, decode and save the - * header. - */ - if (video->bulk.header_size == 0) { - do { - ret = uvc_video_decode_start(video, buf, mem, len); - if (ret == -EAGAIN) - buf = uvc_queue_next_buffer(&video->queue, buf); - } while (ret == -EAGAIN); - - /* If an error occured skip the rest of the payload. */ - if (ret < 0 || buf == NULL) { - video->bulk.skip_payload = 1; - return; - } - - video->bulk.header_size = ret; - memcpy(video->bulk.header, mem, video->bulk.header_size); - - mem += ret; - len -= ret; - } - - /* The buffer queue might have been cancelled while a bulk transfer - * was in progress, so we can reach here with buf equal to NULL. Make - * sure buf is never dereferenced if NULL. - */ - - /* Process video data. */ - if (!video->bulk.skip_payload && buf != NULL) - uvc_video_decode_data(video, buf, mem, len); - - /* Detect the payload end by a URB smaller than the maximum size (or - * a payload size equal to the maximum) and process the header again. - */ - if (urb->actual_length < urb->transfer_buffer_length || - video->bulk.payload_size >= video->bulk.max_payload_size) { - if (!video->bulk.skip_payload && buf != NULL) { - uvc_video_decode_end(video, buf, video->bulk.header, - video->bulk.header_size); - if (buf->state == UVC_BUF_STATE_DONE || - buf->state == UVC_BUF_STATE_ERROR) - buf = uvc_queue_next_buffer(&video->queue, buf); - } - - video->bulk.header_size = 0; - video->bulk.skip_payload = 0; - video->bulk.payload_size = 0; - } -} - -static void uvc_video_complete(struct urb *urb) -{ - struct uvc_video_device *video = urb->context; - struct uvc_video_queue *queue = &video->queue; - struct uvc_buffer *buf = NULL; - unsigned long flags; - int ret; - - switch (urb->status) { - case 0: - break; - - default: - uvc_printk(KERN_WARNING, "Non-zero status (%d) in video " - "completion handler.\n", urb->status); - - case -ENOENT: /* usb_kill_urb() called. */ - if (video->frozen) - return; - - case -ECONNRESET: /* usb_unlink_urb() called. */ - case -ESHUTDOWN: /* The endpoint is being disabled. */ - uvc_queue_cancel(queue, urb->status == -ESHUTDOWN); - return; - } - - spin_lock_irqsave(&queue->irqlock, flags); - if (!list_empty(&queue->irqqueue)) - buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - spin_unlock_irqrestore(&queue->irqlock, flags); - - video->decode(urb, video, buf); - - if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { - uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n", - ret); - } -} - -/* - * Uninitialize isochronous/bulk URBs and free transfer buffers. - */ -static void uvc_uninit_video(struct uvc_video_device *video) -{ - struct urb *urb; - unsigned int i; - - for (i = 0; i < UVC_URBS; ++i) { - if ((urb = video->urb[i]) == NULL) - continue; - - usb_kill_urb(urb); - /* urb->transfer_buffer_length is not touched by USB core, so - * we can use it here as the buffer length. - */ - if (video->urb_buffer[i]) { - usb_buffer_free(video->dev->udev, - urb->transfer_buffer_length, - video->urb_buffer[i], urb->transfer_dma); - video->urb_buffer[i] = NULL; - } - - usb_free_urb(urb); - video->urb[i] = NULL; - } -} - -/* - * Initialize isochronous URBs and allocate transfer buffers. The packet size - * is given by the endpoint. - */ -static int uvc_init_video_isoc(struct uvc_video_device *video, - struct usb_host_endpoint *ep) -{ - struct urb *urb; - unsigned int npackets, i, j; - __u16 psize; - __u32 size; - - /* Compute the number of isochronous packets to allocate by dividing - * the maximum video frame size by the packet size. Limit the result - * to UVC_MAX_ISO_PACKETS. - */ - psize = le16_to_cpu(ep->desc.wMaxPacketSize); - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); - - size = video->streaming->ctrl.dwMaxVideoFrameSize; - if (size > UVC_MAX_FRAME_SIZE) - return -EINVAL; - - npackets = (size + psize - 1) / psize; - if (npackets > UVC_MAX_ISO_PACKETS) - npackets = UVC_MAX_ISO_PACKETS; - - size = npackets * psize; - - for (i = 0; i < UVC_URBS; ++i) { - urb = usb_alloc_urb(npackets, GFP_KERNEL); - if (urb == NULL) { - uvc_uninit_video(video); - return -ENOMEM; - } - - video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, GFP_KERNEL, &urb->transfer_dma); - if (video->urb_buffer[i] == NULL) { - usb_free_urb(urb); - uvc_uninit_video(video); - return -ENOMEM; - } - - urb->dev = video->dev->udev; - urb->context = video; - urb->pipe = usb_rcvisocpipe(video->dev->udev, - ep->desc.bEndpointAddress); - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - urb->interval = ep->desc.bInterval; - urb->transfer_buffer = video->urb_buffer[i]; - urb->complete = uvc_video_complete; - urb->number_of_packets = npackets; - urb->transfer_buffer_length = size; - - for (j = 0; j < npackets; ++j) { - urb->iso_frame_desc[j].offset = j * psize; - urb->iso_frame_desc[j].length = psize; - } - - video->urb[i] = urb; - } - - return 0; -} - -/* - * Initialize bulk URBs and allocate transfer buffers. The packet size is - * given by the endpoint. - */ -static int uvc_init_video_bulk(struct uvc_video_device *video, - struct usb_host_endpoint *ep) -{ - struct urb *urb; - unsigned int pipe, i; - __u16 psize; - __u32 size; - - /* Compute the bulk URB size. Some devices set the maximum payload - * size to a value too high for memory-constrained devices. We must - * then transfer the payload accross multiple URBs. To be consistant - * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk - * URB. - */ - psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff; - size = video->streaming->ctrl.dwMaxPayloadTransferSize; - video->bulk.max_payload_size = size; - if (size > psize * UVC_MAX_ISO_PACKETS) - size = psize * UVC_MAX_ISO_PACKETS; - - pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); - - for (i = 0; i < UVC_URBS; ++i) { - urb = usb_alloc_urb(0, GFP_KERNEL); - if (urb == NULL) { - uvc_uninit_video(video); - return -ENOMEM; - } - - video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, GFP_KERNEL, &urb->transfer_dma); - if (video->urb_buffer[i] == NULL) { - usb_free_urb(urb); - uvc_uninit_video(video); - return -ENOMEM; - } - - usb_fill_bulk_urb(urb, video->dev->udev, pipe, - video->urb_buffer[i], size, uvc_video_complete, - video); - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; - - video->urb[i] = urb; - } - - return 0; -} - -/* - * Initialize isochronous/bulk URBs and allocate transfer buffers. - */ -static int uvc_init_video(struct uvc_video_device *video) -{ - struct usb_interface *intf = video->streaming->intf; - struct usb_host_interface *alts; - struct usb_host_endpoint *ep = NULL; - int intfnum = video->streaming->intfnum; - unsigned int bandwidth, psize, i; - int ret; - - video->last_fid = -1; - video->bulk.header_size = 0; - video->bulk.skip_payload = 0; - video->bulk.payload_size = 0; - - if (intf->num_altsetting > 1) { - /* Isochronous endpoint, select the alternate setting. */ - bandwidth = video->streaming->ctrl.dwMaxPayloadTransferSize; - - if (bandwidth == 0) { - uvc_printk(KERN_WARNING, "device %s requested null " - "bandwidth, defaulting to lowest.\n", - video->vdev->name); - bandwidth = 1; - } - - for (i = 0; i < intf->num_altsetting; ++i) { - alts = &intf->altsetting[i]; - ep = uvc_find_endpoint(alts, - video->streaming->header.bEndpointAddress); - if (ep == NULL) - continue; - - /* Check if the bandwidth is high enough. */ - psize = le16_to_cpu(ep->desc.wMaxPacketSize); - psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); - if (psize >= bandwidth) - break; - } - - if (i >= intf->num_altsetting) - return -EIO; - - if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0) - return ret; - - ret = uvc_init_video_isoc(video, ep); - } else { - /* Bulk endpoint, proceed to URB initialization. */ - ep = uvc_find_endpoint(&intf->altsetting[0], - video->streaming->header.bEndpointAddress); - if (ep == NULL) - return -EIO; - - ret = uvc_init_video_bulk(video, ep); - } - - if (ret < 0) - return ret; - - /* Submit the URBs. */ - for (i = 0; i < UVC_URBS; ++i) { - if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) { - uvc_printk(KERN_ERR, "Failed to submit URB %u " - "(%d).\n", i, ret); - uvc_uninit_video(video); - return ret; - } - } - - return 0; -} - -/* -------------------------------------------------------------------------- - * Suspend/resume - */ - -/* - * Stop streaming without disabling the video queue. - * - * To let userspace applications resume without trouble, we must not touch the - * video buffers in any way. We mark the device as frozen to make sure the URB - * completion handler won't try to cancel the queue when we kill the URBs. - */ -int uvc_video_suspend(struct uvc_video_device *video) -{ - if (!uvc_queue_streaming(&video->queue)) - return 0; - - video->frozen = 1; - uvc_uninit_video(video); - usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); - return 0; -} - -/* - * Reconfigure the video interface and restart streaming if it was enable - * before suspend. - * - * If an error occurs, disable the video queue. This will wake all pending - * buffers, making sure userspace applications are notified of the problem - * instead of waiting forever. - */ -int uvc_video_resume(struct uvc_video_device *video) -{ - int ret; - - video->frozen = 0; - - if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) { - uvc_queue_enable(&video->queue, 0); - return ret; - } - - if (!uvc_queue_streaming(&video->queue)) - return 0; - - if ((ret = uvc_init_video(video)) < 0) - uvc_queue_enable(&video->queue, 0); - - return ret; -} - -/* ------------------------------------------------------------------------ - * Video device - */ - -/* - * Initialize the UVC video device by retrieving the default format and - * committing it. - * - * Some cameras (namely the Fuji Finepix) set the format and frame - * indexes to zero. The UVC standard doesn't clearly make this a spec - * violation, so try to silently fix the values if possible. - * - * This function is called before registering the device with V4L. - */ -int uvc_video_init(struct uvc_video_device *video) -{ - struct uvc_streaming_control *probe = &video->streaming->ctrl; - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; - unsigned int i; - int ret; - - if (video->streaming->nformats == 0) { - uvc_printk(KERN_INFO, "No supported video formats found.\n"); - return -EINVAL; - } - - /* Alternate setting 0 should be the default, yet the XBox Live Vision - * Cam (and possibly other devices) crash or otherwise misbehave if - * they don't receive a SET_INTERFACE request before any other video - * control request. - */ - usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); - - /* Some webcams don't suport GET_DEF request on the probe control. We - * fall back to GET_CUR if GET_DEF fails. - */ - if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 && - (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) - return ret; - - /* Check if the default format descriptor exists. Use the first - * available format otherwise. - */ - for (i = video->streaming->nformats; i > 0; --i) { - format = &video->streaming->format[i-1]; - if (format->index == probe->bFormatIndex) - break; - } - - if (format->nframes == 0) { - uvc_printk(KERN_INFO, "No frame descriptor found for the " - "default format.\n"); - return -EINVAL; - } - - /* Zero bFrameIndex might be correct. Stream-based formats (including - * MPEG-2 TS and DV) do not support frames but have a dummy frame - * descriptor with bFrameIndex set to zero. If the default frame - * descriptor is not found, use the first avalable frame. - */ - for (i = format->nframes; i > 0; --i) { - frame = &format->frame[i-1]; - if (frame->bFrameIndex == probe->bFrameIndex) - break; - } - - /* Commit the default settings. */ - probe->bFormatIndex = format->index; - probe->bFrameIndex = frame->bFrameIndex; - if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0) - return ret; - - video->streaming->cur_format = format; - video->streaming->cur_frame = frame; - atomic_set(&video->active, 0); - - /* Select the video decoding function */ - if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT) - video->decode = uvc_video_decode_isight; - else if (video->streaming->intf->num_altsetting > 1) - video->decode = uvc_video_decode_isoc; - else - video->decode = uvc_video_decode_bulk; - - return 0; -} - -/* - * Enable or disable the video stream. - */ -int uvc_video_enable(struct uvc_video_device *video, int enable) -{ - int ret; - - if (!enable) { - uvc_uninit_video(video); - usb_set_interface(video->dev->udev, - video->streaming->intfnum, 0); - uvc_queue_enable(&video->queue, 0); - return 0; - } - - if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) - return ret; - - return uvc_init_video(video); -} diff --git a/trunk/drivers/media/video/uvc/uvcvideo.h b/trunk/drivers/media/video/uvc/uvcvideo.h deleted file mode 100644 index a995a780db1c..000000000000 --- a/trunk/drivers/media/video/uvc/uvcvideo.h +++ /dev/null @@ -1,796 +0,0 @@ -#ifndef _USB_VIDEO_H_ -#define _USB_VIDEO_H_ - -#include -#include - - -/* - * Dynamic controls - */ - -/* Data types for UVC control data */ -#define UVC_CTRL_DATA_TYPE_RAW 0 -#define UVC_CTRL_DATA_TYPE_SIGNED 1 -#define UVC_CTRL_DATA_TYPE_UNSIGNED 2 -#define UVC_CTRL_DATA_TYPE_BOOLEAN 3 -#define UVC_CTRL_DATA_TYPE_ENUM 4 -#define UVC_CTRL_DATA_TYPE_BITMASK 5 - -/* Control flags */ -#define UVC_CONTROL_SET_CUR (1 << 0) -#define UVC_CONTROL_GET_CUR (1 << 1) -#define UVC_CONTROL_GET_MIN (1 << 2) -#define UVC_CONTROL_GET_MAX (1 << 3) -#define UVC_CONTROL_GET_RES (1 << 4) -#define UVC_CONTROL_GET_DEF (1 << 5) -/* Control should be saved at suspend and restored at resume. */ -#define UVC_CONTROL_RESTORE (1 << 6) -/* Control can be updated by the camera. */ -#define UVC_CONTROL_AUTO_UPDATE (1 << 7) - -#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \ - UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \ - UVC_CONTROL_GET_DEF) - -struct uvc_xu_control_info { - __u8 entity[16]; - __u8 index; - __u8 selector; - __u16 size; - __u32 flags; -}; - -struct uvc_xu_control_mapping { - __u32 id; - __u8 name[32]; - __u8 entity[16]; - __u8 selector; - - __u8 size; - __u8 offset; - enum v4l2_ctrl_type v4l2_type; - __u32 data_type; -}; - -struct uvc_xu_control { - __u8 unit; - __u8 selector; - __u16 size; - __u8 __user *data; -}; - -#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) -#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping) -#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) -#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) - -#ifdef __KERNEL__ - -#include - -/* -------------------------------------------------------------------------- - * UVC constants - */ - -#define SC_UNDEFINED 0x00 -#define SC_VIDEOCONTROL 0x01 -#define SC_VIDEOSTREAMING 0x02 -#define SC_VIDEO_INTERFACE_COLLECTION 0x03 - -#define PC_PROTOCOL_UNDEFINED 0x00 - -#define CS_UNDEFINED 0x20 -#define CS_DEVICE 0x21 -#define CS_CONFIGURATION 0x22 -#define CS_STRING 0x23 -#define CS_INTERFACE 0x24 -#define CS_ENDPOINT 0x25 - -/* VideoControl class specific interface descriptor */ -#define VC_DESCRIPTOR_UNDEFINED 0x00 -#define VC_HEADER 0x01 -#define VC_INPUT_TERMINAL 0x02 -#define VC_OUTPUT_TERMINAL 0x03 -#define VC_SELECTOR_UNIT 0x04 -#define VC_PROCESSING_UNIT 0x05 -#define VC_EXTENSION_UNIT 0x06 - -/* VideoStreaming class specific interface descriptor */ -#define VS_UNDEFINED 0x00 -#define VS_INPUT_HEADER 0x01 -#define VS_OUTPUT_HEADER 0x02 -#define VS_STILL_IMAGE_FRAME 0x03 -#define VS_FORMAT_UNCOMPRESSED 0x04 -#define VS_FRAME_UNCOMPRESSED 0x05 -#define VS_FORMAT_MJPEG 0x06 -#define VS_FRAME_MJPEG 0x07 -#define VS_FORMAT_MPEG2TS 0x0a -#define VS_FORMAT_DV 0x0c -#define VS_COLORFORMAT 0x0d -#define VS_FORMAT_FRAME_BASED 0x10 -#define VS_FRAME_FRAME_BASED 0x11 -#define VS_FORMAT_STREAM_BASED 0x12 - -/* Endpoint type */ -#define EP_UNDEFINED 0x00 -#define EP_GENERAL 0x01 -#define EP_ENDPOINT 0x02 -#define EP_INTERRUPT 0x03 - -/* Request codes */ -#define RC_UNDEFINED 0x00 -#define SET_CUR 0x01 -#define GET_CUR 0x81 -#define GET_MIN 0x82 -#define GET_MAX 0x83 -#define GET_RES 0x84 -#define GET_LEN 0x85 -#define GET_INFO 0x86 -#define GET_DEF 0x87 - -/* VideoControl interface controls */ -#define VC_CONTROL_UNDEFINED 0x00 -#define VC_VIDEO_POWER_MODE_CONTROL 0x01 -#define VC_REQUEST_ERROR_CODE_CONTROL 0x02 - -/* Terminal controls */ -#define TE_CONTROL_UNDEFINED 0x00 - -/* Selector Unit controls */ -#define SU_CONTROL_UNDEFINED 0x00 -#define SU_INPUT_SELECT_CONTROL 0x01 - -/* Camera Terminal controls */ -#define CT_CONTROL_UNDEFINED 0x00 -#define CT_SCANNING_MODE_CONTROL 0x01 -#define CT_AE_MODE_CONTROL 0x02 -#define CT_AE_PRIORITY_CONTROL 0x03 -#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 -#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 -#define CT_FOCUS_ABSOLUTE_CONTROL 0x06 -#define CT_FOCUS_RELATIVE_CONTROL 0x07 -#define CT_FOCUS_AUTO_CONTROL 0x08 -#define CT_IRIS_ABSOLUTE_CONTROL 0x09 -#define CT_IRIS_RELATIVE_CONTROL 0x0a -#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b -#define CT_ZOOM_RELATIVE_CONTROL 0x0c -#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d -#define CT_PANTILT_RELATIVE_CONTROL 0x0e -#define CT_ROLL_ABSOLUTE_CONTROL 0x0f -#define CT_ROLL_RELATIVE_CONTROL 0x10 -#define CT_PRIVACY_CONTROL 0x11 - -/* Processing Unit controls */ -#define PU_CONTROL_UNDEFINED 0x00 -#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 -#define PU_BRIGHTNESS_CONTROL 0x02 -#define PU_CONTRAST_CONTROL 0x03 -#define PU_GAIN_CONTROL 0x04 -#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 -#define PU_HUE_CONTROL 0x06 -#define PU_SATURATION_CONTROL 0x07 -#define PU_SHARPNESS_CONTROL 0x08 -#define PU_GAMMA_CONTROL 0x09 -#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a -#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b -#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c -#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d -#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e -#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f -#define PU_HUE_AUTO_CONTROL 0x10 -#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 -#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 - -#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01 -#define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02 -#define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03 - -/* VideoStreaming interface controls */ -#define VS_CONTROL_UNDEFINED 0x00 -#define VS_PROBE_CONTROL 0x01 -#define VS_COMMIT_CONTROL 0x02 -#define VS_STILL_PROBE_CONTROL 0x03 -#define VS_STILL_COMMIT_CONTROL 0x04 -#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 -#define VS_STREAM_ERROR_CODE_CONTROL 0x06 -#define VS_GENERATE_KEY_FRAME_CONTROL 0x07 -#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 -#define VS_SYNC_DELAY_CONTROL 0x09 - -#define TT_VENDOR_SPECIFIC 0x0100 -#define TT_STREAMING 0x0101 - -/* Input Terminal types */ -#define ITT_VENDOR_SPECIFIC 0x0200 -#define ITT_CAMERA 0x0201 -#define ITT_MEDIA_TRANSPORT_INPUT 0x0202 - -/* Output Terminal types */ -#define OTT_VENDOR_SPECIFIC 0x0300 -#define OTT_DISPLAY 0x0301 -#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 - -/* External Terminal types */ -#define EXTERNAL_VENDOR_SPECIFIC 0x0400 -#define COMPOSITE_CONNECTOR 0x0401 -#define SVIDEO_CONNECTOR 0x0402 -#define COMPONENT_CONNECTOR 0x0403 - -#define UVC_TERM_INPUT 0x0000 -#define UVC_TERM_OUTPUT 0x8000 - -#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) -#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) -#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0) -#define UVC_ENTITY_IS_ITERM(entity) \ - (((entity)->type & 0x8000) == UVC_TERM_INPUT) -#define UVC_ENTITY_IS_OTERM(entity) \ - (((entity)->type & 0x8000) == UVC_TERM_OUTPUT) - -#define UVC_STATUS_TYPE_CONTROL 1 -#define UVC_STATUS_TYPE_STREAMING 2 - -/* ------------------------------------------------------------------------ - * GUIDs - */ -#define UVC_GUID_UVC_CAMERA \ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} -#define UVC_GUID_UVC_OUTPUT \ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02} -#define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03} -#define UVC_GUID_UVC_PROCESSING \ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01} -#define UVC_GUID_UVC_SELECTOR \ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02} - -#define UVC_GUID_LOGITECH_DEV_INFO \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1e} -#define UVC_GUID_LOGITECH_USER_HW \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f} -#define UVC_GUID_LOGITECH_VIDEO \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x50} -#define UVC_GUID_LOGITECH_MOTOR \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56} - -#define UVC_GUID_FORMAT_MJPEG \ - { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -#define UVC_GUID_FORMAT_YUY2 \ - { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -#define UVC_GUID_FORMAT_NV12 \ - { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -#define UVC_GUID_FORMAT_YV12 \ - { 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -#define UVC_GUID_FORMAT_I420 \ - { 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -#define UVC_GUID_FORMAT_UYVY \ - { 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -#define UVC_GUID_FORMAT_Y800 \ - { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -#define UVC_GUID_FORMAT_BY8 \ - { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} - - -/* ------------------------------------------------------------------------ - * Driver specific constants. - */ - -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0) - -/* Number of isochronous URBs. */ -#define UVC_URBS 5 -/* Maximum number of packets per isochronous URB. */ -#define UVC_MAX_ISO_PACKETS 40 -/* Maximum frame size in bytes, for sanity checking. */ -#define UVC_MAX_FRAME_SIZE (16*1024*1024) -/* Maximum number of video buffers. */ -#define UVC_MAX_VIDEO_BUFFERS 32 - -#define UVC_CTRL_CONTROL_TIMEOUT 300 -#define UVC_CTRL_STREAMING_TIMEOUT 1000 - -/* Devices quirks */ -#define UVC_QUIRK_STATUS_INTERVAL 0x00000001 -#define UVC_QUIRK_PROBE_MINMAX 0x00000002 -#define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004 -#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 -#define UVC_QUIRK_STREAM_NO_FID 0x00000010 -#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 - -/* Format flags */ -#define UVC_FMT_FLAG_COMPRESSED 0x00000001 -#define UVC_FMT_FLAG_STREAM 0x00000002 - -/* ------------------------------------------------------------------------ - * Structures. - */ - -struct uvc_device; - -/* TODO: Put the most frequently accessed fields at the beginning of - * structures to maximize cache efficiency. - */ -struct uvc_streaming_control { - __u16 bmHint; - __u8 bFormatIndex; - __u8 bFrameIndex; - __u32 dwFrameInterval; - __u16 wKeyFrameRate; - __u16 wPFrameRate; - __u16 wCompQuality; - __u16 wCompWindowSize; - __u16 wDelay; - __u32 dwMaxVideoFrameSize; - __u32 dwMaxPayloadTransferSize; - __u32 dwClockFrequency; - __u8 bmFramingInfo; - __u8 bPreferedVersion; - __u8 bMinVersion; - __u8 bMaxVersion; -}; - -struct uvc_menu_info { - __u32 value; - __u8 name[32]; -}; - -struct uvc_control_info { - struct list_head list; - struct list_head mappings; - - __u8 entity[16]; - __u8 index; - __u8 selector; - - __u16 size; - __u32 flags; -}; - -struct uvc_control_mapping { - struct list_head list; - - struct uvc_control_info *ctrl; - - __u32 id; - __u8 name[32]; - __u8 entity[16]; - __u8 selector; - - __u8 size; - __u8 offset; - enum v4l2_ctrl_type v4l2_type; - __u32 data_type; - - struct uvc_menu_info *menu_info; - __u32 menu_count; -}; - -struct uvc_control { - struct uvc_entity *entity; - struct uvc_control_info *info; - - __u8 index; /* Used to match the uvc_control entry with a - uvc_control_info. */ - __u8 dirty : 1, - loaded : 1, - modified : 1; - - __u8 *data; -}; - -struct uvc_format_desc { - char *name; - __u8 guid[16]; - __u32 fcc; -}; - -/* The term 'entity' refers to both UVC units and UVC terminals. - * - * The type field is either the terminal type (wTerminalType in the terminal - * descriptor), or the unit type (bDescriptorSubtype in the unit descriptor). - * As the bDescriptorSubtype field is one byte long, the type value will - * always have a null MSB for units. All terminal types defined by the UVC - * specification have a non-null MSB, so it is safe to use the MSB to - * differentiate between units and terminals as long as the descriptor parsing - * code makes sure terminal types have a non-null MSB. - * - * For terminals, the type's most significant bit stores the terminal - * direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should - * always be accessed with the UVC_ENTITY_* macros and never directly. - */ - -struct uvc_entity { - struct list_head list; /* Entity as part of a UVC device. */ - struct list_head chain; /* Entity as part of a video device - * chain. */ - __u8 id; - __u16 type; - char name[64]; - - union { - struct { - __u16 wObjectiveFocalLengthMin; - __u16 wObjectiveFocalLengthMax; - __u16 wOcularFocalLength; - __u8 bControlSize; - __u8 *bmControls; - } camera; - - struct { - __u8 bControlSize; - __u8 *bmControls; - __u8 bTransportModeSize; - __u8 *bmTransportModes; - } media; - - struct { - __u8 bSourceID; - } output; - - struct { - __u8 bSourceID; - __u16 wMaxMultiplier; - __u8 bControlSize; - __u8 *bmControls; - __u8 bmVideoStandards; - } processing; - - struct { - __u8 bNrInPins; - __u8 *baSourceID; - } selector; - - struct { - __u8 guidExtensionCode[16]; - __u8 bNumControls; - __u8 bNrInPins; - __u8 *baSourceID; - __u8 bControlSize; - __u8 *bmControls; - __u8 *bmControlsType; - } extension; - }; - - unsigned int ncontrols; - struct uvc_control *controls; -}; - -struct uvc_frame { - __u8 bFrameIndex; - __u8 bmCapabilities; - __u16 wWidth; - __u16 wHeight; - __u32 dwMinBitRate; - __u32 dwMaxBitRate; - __u32 dwMaxVideoFrameBufferSize; - __u8 bFrameIntervalType; - __u32 dwDefaultFrameInterval; - __u32 *dwFrameInterval; -}; - -struct uvc_format { - __u8 type; - __u8 index; - __u8 bpp; - __u8 colorspace; - __u32 fcc; - __u32 flags; - - char name[32]; - - unsigned int nframes; - struct uvc_frame *frame; -}; - -struct uvc_streaming_header { - __u8 bNumFormats; - __u8 bEndpointAddress; - __u8 bTerminalLink; - __u8 bControlSize; - __u8 *bmaControls; - /* The following fields are used by input headers only. */ - __u8 bmInfo; - __u8 bStillCaptureMethod; - __u8 bTriggerSupport; - __u8 bTriggerUsage; -}; - -struct uvc_streaming { - struct list_head list; - - struct usb_interface *intf; - int intfnum; - __u16 maxpsize; - - struct uvc_streaming_header header; - - unsigned int nformats; - struct uvc_format *format; - - struct uvc_streaming_control ctrl; - struct uvc_format *cur_format; - struct uvc_frame *cur_frame; - - struct mutex mutex; -}; - -enum uvc_buffer_state { - UVC_BUF_STATE_IDLE = 0, - UVC_BUF_STATE_QUEUED = 1, - UVC_BUF_STATE_ACTIVE = 2, - UVC_BUF_STATE_DONE = 3, - UVC_BUF_STATE_ERROR = 4, -}; - -struct uvc_buffer { - unsigned long vma_use_count; - struct list_head stream; - - /* Touched by interrupt handler. */ - struct v4l2_buffer buf; - struct list_head queue; - wait_queue_head_t wait; - enum uvc_buffer_state state; -}; - -#define UVC_QUEUE_STREAMING (1 << 0) -#define UVC_QUEUE_DISCONNECTED (1 << 1) -#define UVC_QUEUE_DROP_INCOMPLETE (1 << 2) - -struct uvc_video_queue { - void *mem; - unsigned int flags; - __u32 sequence; - - unsigned int count; - unsigned int buf_size; - struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS]; - struct mutex mutex; /* protects buffers and mainqueue */ - spinlock_t irqlock; /* protects irqqueue */ - - struct list_head mainqueue; - struct list_head irqqueue; -}; - -struct uvc_video_device { - struct uvc_device *dev; - struct video_device *vdev; - atomic_t active; - unsigned int frozen : 1; - - struct list_head iterms; - struct uvc_entity *oterm; - struct uvc_entity *processing; - struct uvc_entity *selector; - struct list_head extensions; - struct mutex ctrl_mutex; - - struct uvc_video_queue queue; - - /* Video streaming object, must always be non-NULL. */ - struct uvc_streaming *streaming; - - void (*decode) (struct urb *urb, struct uvc_video_device *video, - struct uvc_buffer *buf); - - /* Context data used by the bulk completion handler. */ - struct { - __u8 header[256]; - unsigned int header_size; - int skip_payload; - __u32 payload_size; - __u32 max_payload_size; - } bulk; - - struct urb *urb[UVC_URBS]; - char *urb_buffer[UVC_URBS]; - - __u8 last_fid; -}; - -enum uvc_device_state { - UVC_DEV_DISCONNECTED = 1, -}; - -struct uvc_device { - struct usb_device *udev; - struct usb_interface *intf; - __u32 quirks; - int intfnum; - char name[32]; - - enum uvc_device_state state; - struct kref kref; - struct list_head list; - - /* Video control interface */ - __u16 uvc_version; - __u32 clock_frequency; - - struct list_head entities; - - struct uvc_video_device video; - - /* Status Interrupt Endpoint */ - struct usb_host_endpoint *int_ep; - struct urb *int_urb; - __u8 status[16]; - struct input_dev *input; - - /* Video Streaming interfaces */ - struct list_head streaming; -}; - -enum uvc_handle_state { - UVC_HANDLE_PASSIVE = 0, - UVC_HANDLE_ACTIVE = 1, -}; - -struct uvc_fh { - struct uvc_video_device *device; - enum uvc_handle_state state; -}; - -struct uvc_driver { - struct usb_driver driver; - - struct mutex open_mutex; /* protects from open/disconnect race */ - - struct list_head devices; /* struct uvc_device list */ - struct list_head controls; /* struct uvc_control_info list */ - struct mutex ctrl_mutex; /* protects controls and devices - lists */ -}; - -/* ------------------------------------------------------------------------ - * Debugging, printing and logging - */ - -#define UVC_TRACE_PROBE (1 << 0) -#define UVC_TRACE_DESCR (1 << 1) -#define UVC_TRACE_CONTROL (1 << 2) -#define UVC_TRACE_FORMAT (1 << 3) -#define UVC_TRACE_CAPTURE (1 << 4) -#define UVC_TRACE_CALLS (1 << 5) -#define UVC_TRACE_IOCTL (1 << 6) -#define UVC_TRACE_FRAME (1 << 7) -#define UVC_TRACE_SUSPEND (1 << 8) -#define UVC_TRACE_STATUS (1 << 9) - -extern unsigned int uvc_trace_param; - -#define uvc_trace(flag, msg...) \ - do { \ - if (uvc_trace_param & flag) \ - printk(KERN_DEBUG "uvcvideo: " msg); \ - } while (0) - -#define uvc_printk(level, msg...) \ - printk(level "uvcvideo: " msg) - -#define UVC_GUID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \ - "%02x%02x%02x%02x%02x%02x" -#define UVC_GUID_ARGS(guid) \ - (guid)[3], (guid)[2], (guid)[1], (guid)[0], \ - (guid)[5], (guid)[4], \ - (guid)[7], (guid)[6], \ - (guid)[8], (guid)[9], \ - (guid)[10], (guid)[11], (guid)[12], \ - (guid)[13], (guid)[14], (guid)[15] - -/* -------------------------------------------------------------------------- - * Internal functions. - */ - -/* Core driver */ -extern struct uvc_driver uvc_driver; -extern void uvc_delete(struct kref *kref); - -/* Video buffers queue management. */ -extern void uvc_queue_init(struct uvc_video_queue *queue); -extern int uvc_alloc_buffers(struct uvc_video_queue *queue, - unsigned int nbuffers, unsigned int buflength); -extern int uvc_free_buffers(struct uvc_video_queue *queue); -extern int uvc_query_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf); -extern int uvc_queue_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf); -extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, - struct v4l2_buffer *v4l2_buf, int nonblocking); -extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); -extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); -extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, - struct uvc_buffer *buf); -extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, - struct file *file, poll_table *wait); -static inline int uvc_queue_streaming(struct uvc_video_queue *queue) -{ - return queue->flags & UVC_QUEUE_STREAMING; -} - -/* V4L2 interface */ -extern struct file_operations uvc_fops; - -/* Video */ -extern int uvc_video_init(struct uvc_video_device *video); -extern int uvc_video_suspend(struct uvc_video_device *video); -extern int uvc_video_resume(struct uvc_video_device *video); -extern int uvc_video_enable(struct uvc_video_device *video, int enable); -extern int uvc_probe_video(struct uvc_video_device *video, - struct uvc_streaming_control *probe); -extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, - __u8 intfnum, __u8 cs, void *data, __u16 size); -extern int uvc_set_video_ctrl(struct uvc_video_device *video, - struct uvc_streaming_control *ctrl, int probe); - -/* Status */ -extern int uvc_status_init(struct uvc_device *dev); -extern void uvc_status_cleanup(struct uvc_device *dev); -extern int uvc_status_suspend(struct uvc_device *dev); -extern int uvc_status_resume(struct uvc_device *dev); - -/* Controls */ -extern struct uvc_control *uvc_find_control(struct uvc_video_device *video, - __u32 v4l2_id, struct uvc_control_mapping **mapping); -extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video, - struct v4l2_queryctrl *v4l2_ctrl); - -extern int uvc_ctrl_add_info(struct uvc_control_info *info); -extern int uvc_ctrl_add_mapping(struct uvc_control_mapping *mapping); -extern int uvc_ctrl_init_device(struct uvc_device *dev); -extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); -extern int uvc_ctrl_resume_device(struct uvc_device *dev); -extern void uvc_ctrl_init(void); - -extern int uvc_ctrl_begin(struct uvc_video_device *video); -extern int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback); -static inline int uvc_ctrl_commit(struct uvc_video_device *video) -{ - return __uvc_ctrl_commit(video, 0); -} -static inline int uvc_ctrl_rollback(struct uvc_video_device *video) -{ - return __uvc_ctrl_commit(video, 1); -} - -extern int uvc_ctrl_get(struct uvc_video_device *video, - struct v4l2_ext_control *xctrl); -extern int uvc_ctrl_set(struct uvc_video_device *video, - struct v4l2_ext_control *xctrl); - -extern int uvc_xu_ctrl_query(struct uvc_video_device *video, - struct uvc_xu_control *ctrl, int set); - -/* Utility functions */ -extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, - unsigned int n_terms, unsigned int threshold); -extern uint32_t uvc_fraction_to_interval(uint32_t numerator, - uint32_t denominator); -extern struct usb_host_endpoint *uvc_find_endpoint( - struct usb_host_interface *alts, __u8 epaddr); - -/* Quirks support */ -void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, - struct uvc_buffer *buf); - -#endif /* __KERNEL__ */ - -#endif diff --git a/trunk/drivers/media/video/videodev.c b/trunk/drivers/media/video/videodev.c index 67a661cf5219..31e8af0ba278 100644 --- a/trunk/drivers/media/video/videodev.c +++ b/trunk/drivers/media/video/videodev.c @@ -51,51 +51,12 @@ #define VIDEO_NUM_DEVICES 256 #define VIDEO_NAME "video4linux" -struct std_descr { - v4l2_std_id std; - const char *descr; -}; - -static const struct std_descr standards[] = { - { V4L2_STD_NTSC, "NTSC" }, - { V4L2_STD_NTSC_M, "NTSC-M" }, - { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, - { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, - { V4L2_STD_NTSC_443, "NTSC-443" }, - { V4L2_STD_PAL, "PAL" }, - { V4L2_STD_PAL_BG, "PAL-BG" }, - { V4L2_STD_PAL_B, "PAL-B" }, - { V4L2_STD_PAL_B1, "PAL-B1" }, - { V4L2_STD_PAL_G, "PAL-G" }, - { V4L2_STD_PAL_H, "PAL-H" }, - { V4L2_STD_PAL_I, "PAL-I" }, - { V4L2_STD_PAL_DK, "PAL-DK" }, - { V4L2_STD_PAL_D, "PAL-D" }, - { V4L2_STD_PAL_D1, "PAL-D1" }, - { V4L2_STD_PAL_K, "PAL-K" }, - { V4L2_STD_PAL_M, "PAL-M" }, - { V4L2_STD_PAL_N, "PAL-N" }, - { V4L2_STD_PAL_Nc, "PAL-Nc" }, - { V4L2_STD_PAL_60, "PAL-60" }, - { V4L2_STD_SECAM, "SECAM" }, - { V4L2_STD_SECAM_B, "SECAM-B" }, - { V4L2_STD_SECAM_G, "SECAM-G" }, - { V4L2_STD_SECAM_H, "SECAM-H" }, - { V4L2_STD_SECAM_DK, "SECAM-DK" }, - { V4L2_STD_SECAM_D, "SECAM-D" }, - { V4L2_STD_SECAM_K, "SECAM-K" }, - { V4L2_STD_SECAM_K1, "SECAM-K1" }, - { V4L2_STD_SECAM_L, "SECAM-L" }, - { V4L2_STD_SECAM_LC, "SECAM-Lc" }, - { 0, "Unknown" } -}; - /* video4linux standard ID conversion to standard name */ -const char *v4l2_norm_to_name(v4l2_std_id id) +char *v4l2_norm_to_name(v4l2_std_id id) { + char *name; u32 myid = id; - int i; /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle 64 bit comparations. So, on that architecture, with some gcc @@ -103,17 +64,110 @@ const char *v4l2_norm_to_name(v4l2_std_id id) */ BUG_ON(myid != id); - for (i = 0; standards[i].std; i++) - if (myid == standards[i].std) - break; - return standards[i].descr; + switch (myid) { + case V4L2_STD_PAL: + name = "PAL"; + break; + case V4L2_STD_PAL_BG: + name = "PAL-BG"; + break; + case V4L2_STD_PAL_DK: + name = "PAL-DK"; + break; + case V4L2_STD_PAL_B: + name = "PAL-B"; + break; + case V4L2_STD_PAL_B1: + name = "PAL-B1"; + break; + case V4L2_STD_PAL_G: + name = "PAL-G"; + break; + case V4L2_STD_PAL_H: + name = "PAL-H"; + break; + case V4L2_STD_PAL_I: + name = "PAL-I"; + break; + case V4L2_STD_PAL_D: + name = "PAL-D"; + break; + case V4L2_STD_PAL_D1: + name = "PAL-D1"; + break; + case V4L2_STD_PAL_K: + name = "PAL-K"; + break; + case V4L2_STD_PAL_M: + name = "PAL-M"; + break; + case V4L2_STD_PAL_N: + name = "PAL-N"; + break; + case V4L2_STD_PAL_Nc: + name = "PAL-Nc"; + break; + case V4L2_STD_PAL_60: + name = "PAL-60"; + break; + case V4L2_STD_NTSC: + name = "NTSC"; + break; + case V4L2_STD_NTSC_M: + name = "NTSC-M"; + break; + case V4L2_STD_NTSC_M_JP: + name = "NTSC-M-JP"; + break; + case V4L2_STD_NTSC_443: + name = "NTSC-443"; + break; + case V4L2_STD_NTSC_M_KR: + name = "NTSC-M-KR"; + break; + case V4L2_STD_SECAM: + name = "SECAM"; + break; + case V4L2_STD_SECAM_DK: + name = "SECAM-DK"; + break; + case V4L2_STD_SECAM_B: + name = "SECAM-B"; + break; + case V4L2_STD_SECAM_D: + name = "SECAM-D"; + break; + case V4L2_STD_SECAM_G: + name = "SECAM-G"; + break; + case V4L2_STD_SECAM_H: + name = "SECAM-H"; + break; + case V4L2_STD_SECAM_K: + name = "SECAM-K"; + break; + case V4L2_STD_SECAM_K1: + name = "SECAM-K1"; + break; + case V4L2_STD_SECAM_L: + name = "SECAM-L"; + break; + case V4L2_STD_SECAM_LC: + name = "SECAM-LC"; + break; + default: + name = "Unknown"; + break; + } + + return name; } EXPORT_SYMBOL(v4l2_norm_to_name); /* Fill in the fields of a v4l2_standard structure according to the 'id' and 'transmission' parameters. Returns negative on error. */ int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, const char *name) + int id, char *name) { u32 index = vs->index; @@ -1164,40 +1218,95 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_ENUMSTD: { struct v4l2_standard *p = arg; - v4l2_std_id id = vfd->tvnorms, curr_id = 0; - unsigned int index = p->index, i, j = 0; - const char *descr = ""; - - /* Return norm array in a canonical way */ - for (i = 0; i <= index && id; i++) { - /* last std value in the standards array is 0, so this - while always ends there since (id & 0) == 0. */ - while ((id & standards[j].std) != standards[j].std) - j++; - curr_id = standards[j].std; - descr = standards[j].descr; - j++; - if (curr_id == 0) + v4l2_std_id id = vfd->tvnorms,curr_id=0; + unsigned int index = p->index,i; + + if (index<0) { + ret=-EINVAL; + break; + } + + /* Return norm array on a canonical way */ + for (i=0;i<= index && id; i++) { + if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) { + curr_id = V4L2_STD_PAL; + } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) { + curr_id = V4L2_STD_PAL_BG; + } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) { + curr_id = V4L2_STD_PAL_DK; + } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) { + curr_id = V4L2_STD_PAL_B; + } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) { + curr_id = V4L2_STD_PAL_B1; + } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) { + curr_id = V4L2_STD_PAL_G; + } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) { + curr_id = V4L2_STD_PAL_H; + } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) { + curr_id = V4L2_STD_PAL_I; + } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) { + curr_id = V4L2_STD_PAL_D; + } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) { + curr_id = V4L2_STD_PAL_D1; + } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) { + curr_id = V4L2_STD_PAL_K; + } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) { + curr_id = V4L2_STD_PAL_M; + } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) { + curr_id = V4L2_STD_PAL_N; + } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) { + curr_id = V4L2_STD_PAL_Nc; + } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) { + curr_id = V4L2_STD_PAL_60; + } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) { + curr_id = V4L2_STD_NTSC; + } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) { + curr_id = V4L2_STD_NTSC_M; + } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) { + curr_id = V4L2_STD_NTSC_M_JP; + } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) { + curr_id = V4L2_STD_NTSC_443; + } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) { + curr_id = V4L2_STD_NTSC_M_KR; + } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) { + curr_id = V4L2_STD_SECAM; + } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) { + curr_id = V4L2_STD_SECAM_DK; + } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) { + curr_id = V4L2_STD_SECAM_B; + } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) { + curr_id = V4L2_STD_SECAM_D; + } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) { + curr_id = V4L2_STD_SECAM_G; + } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) { + curr_id = V4L2_STD_SECAM_H; + } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) { + curr_id = V4L2_STD_SECAM_K; + } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) { + curr_id = V4L2_STD_SECAM_K1; + } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) { + curr_id = V4L2_STD_SECAM_L; + } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) { + curr_id = V4L2_STD_SECAM_LC; + } else { break; - if (curr_id != V4L2_STD_PAL && - curr_id != V4L2_STD_SECAM && - curr_id != V4L2_STD_NTSC) - id &= ~curr_id; + } + id &= ~curr_id; } - if (i <= index) + if (i<=index) return -EINVAL; - v4l2_video_std_construct(p, curr_id, descr); + v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id)); p->index = index; - dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " + dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " "framelines=%d\n", p->index, (unsigned long long)p->id, p->name, p->frameperiod.numerator, p->frameperiod.denominator, p->framelines); - ret = 0; + ret=0; break; } case VIDIOC_G_STD: diff --git a/trunk/drivers/media/video/vivi.c b/trunk/drivers/media/video/vivi.c index 5ff9a58b6135..845be1864f68 100644 --- a/trunk/drivers/media/video/vivi.c +++ b/trunk/drivers/media/video/vivi.c @@ -327,14 +327,13 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) int hmax = buf->vb.height; int wmax = buf->vb.width; struct timeval ts; - char *tmpbuf; + char *tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); void *vbuf = videobuf_to_vmalloc(&buf->vb); - if (!vbuf) + if (!tmpbuf) return; - tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC); - if (!tmpbuf) + if (!vbuf) return; for (h = 0; h < hmax; h++) { diff --git a/trunk/drivers/mtd/maps/omap_nor.c b/trunk/drivers/mtd/maps/omap_nor.c index 68eec6c6c517..c12d8056bebd 100644 --- a/trunk/drivers/mtd/maps/omap_nor.c +++ b/trunk/drivers/mtd/maps/omap_nor.c @@ -60,22 +60,13 @@ struct omapflash_info { static void omap_set_vpp(struct map_info *map, int enable) { static int count; - u32 l; - - if (cpu_class_is_omap1()) { - if (enable) { - if (count++ == 0) { - l = omap_readl(EMIFS_CONFIG); - l |= OMAP_EMIFS_CONFIG_WP; - omap_writel(l, EMIFS_CONFIG); - } - } else { - if (count && (--count == 0)) { - l = omap_readl(EMIFS_CONFIG); - l &= ~OMAP_EMIFS_CONFIG_WP; - omap_writel(l, EMIFS_CONFIG); - } - } + + if (enable) { + if (count++ == 0) + OMAP_EMIFS_CONFIG_REG |= OMAP_EMIFS_CONFIG_WP; + } else { + if (count && (--count == 0)) + OMAP_EMIFS_CONFIG_REG &= ~OMAP_EMIFS_CONFIG_WP; } } diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index aabad8ce7458..2edda8cc7f99 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -1768,10 +1768,9 @@ vortex_timer(unsigned long data) case XCVR_MII: case XCVR_NWAY: { ok = 1; - /* Interrupts are already disabled */ - spin_lock(&vp->lock); + spin_lock_bh(&vp->lock); vortex_check_media(dev, 0); - spin_unlock(&vp->lock); + spin_unlock_bh(&vp->lock); } break; default: /* Other media types handled by Tx timeouts. */ diff --git a/trunk/drivers/net/arm/etherh.c b/trunk/drivers/net/arm/etherh.c index 00081d2b9cd5..e9d15eccad08 100644 --- a/trunk/drivers/net/arm/etherh.c +++ b/trunk/drivers/net/arm/etherh.c @@ -647,7 +647,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) struct ei_device *ei_local; struct net_device *dev; struct etherh_priv *eh; - int i, ret; + int ret; DECLARE_MAC_BUF(mac); etherh_banner(); diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index 1037b1332312..f3cba5e24ec5 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -1803,8 +1803,6 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) if (rx->prev->skb) { struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; put_unaligned_le32(rx->dma_addr, &prev_rfd->link); - pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, - sizeof(struct rfd), PCI_DMA_TODEVICE); } return 0; diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index a3f6a9c72ec8..701531e72e7b 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -347,7 +347,7 @@ e1000_set_tso(struct net_device *netdev, u32 data) else netdev->features &= ~NETIF_F_TSO; - if (data && (adapter->hw.mac_type > e1000_82547_rev_2)) + if (data) netdev->features |= NETIF_F_TSO6; else netdev->features &= ~NETIF_F_TSO6; diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 648a87bbf467..cab1835173cd 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -2535,8 +2535,7 @@ void e1000e_down(struct e1000_adapter *adapter) adapter->link_speed = 0; adapter->link_duplex = 0; - if (!pci_channel_offline(adapter->pdev)) - e1000e_reset(adapter); + e1000e_reset(adapter); e1000_clean_tx_ring(adapter); e1000_clean_rx_ring(adapter); diff --git a/trunk/drivers/net/hamradio/dmascc.c b/trunk/drivers/net/hamradio/dmascc.c index e8cfadefa4b6..0b94833e23f7 100644 --- a/trunk/drivers/net/hamradio/dmascc.c +++ b/trunk/drivers/net/hamradio/dmascc.c @@ -1077,6 +1077,8 @@ static inline void rx_off(struct scc_priv *priv) static void start_timer(struct scc_priv *priv, int t, int r15) { + unsigned long flags; + outb(priv->tmr_mode, priv->tmr_ctrl); if (t == 0) { tm_isr(priv); diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index e79a26a886c8..ae398f04c7b4 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -718,8 +718,7 @@ void igb_down(struct igb_adapter *adapter) adapter->link_speed = 0; adapter->link_duplex = 0; - if (!pci_channel_offline(adapter->pdev)) - igb_reset(adapter); + igb_reset(adapter); igb_clean_all_tx_rings(adapter); igb_clean_all_rx_rings(adapter); } diff --git a/trunk/drivers/net/ipg.c b/trunk/drivers/net/ipg.c index 2c03f4e2ccc4..679a0826780e 100644 --- a/trunk/drivers/net/ipg.c +++ b/trunk/drivers/net/ipg.c @@ -1271,7 +1271,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev, framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; - endframelen = framelen - jumbo->current_size; + endframeLen = framelen - jumbo->current_size; /* if (framelen > IPG_RXFRAG_SIZE) framelen=IPG_RXFRAG_SIZE; @@ -1279,8 +1279,8 @@ static void ipg_nic_rx_with_end(struct net_device *dev, if (framelen > IPG_RXSUPPORT_SIZE) dev_kfree_skb_irq(jumbo->skb); else { - memcpy(skb_put(jumbo->skb, endframelen), - skb->data, endframelen); + memcpy(skb_put(jumbo->skb, endframeLen), + skb->data, endframeLen); jumbo->skb->protocol = eth_type_trans(jumbo->skb, dev); @@ -1352,16 +1352,16 @@ static int ipg_nic_rx(struct net_device *dev) switch (ipg_nic_rx_check_frame_type(dev)) { case FRAME_WITH_START_WITH_END: - ipg_nic_rx_with_start_and_end(dev, sp, rxfd, entry); + ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry); break; case FRAME_WITH_START: - ipg_nic_rx_with_start(dev, sp, rxfd, entry); + ipg_nic_rx_with_start(dev, tp, rxfd, entry); break; case FRAME_WITH_END: - ipg_nic_rx_with_end(dev, sp, rxfd, entry); + ipg_nic_rx_with_end(dev, tp, rxfd, entry); break; case FRAME_NO_START_NO_END: - ipg_nic_rx_no_start_no_end(dev, sp, rxfd, entry); + ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry); break; } } @@ -1808,7 +1808,7 @@ static int ipg_nic_open(struct net_device *dev) /* initialize JUMBO Frame control variable */ sp->jumbo.found_start = 0; sp->jumbo.current_size = 0; - sp->jumbo.skb = NULL; + sp->jumbo.skb = 0; dev->mtu = IPG_TXFRAG_SIZE; #endif diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 8f0460901153..7b859220c255 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -1969,8 +1969,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) netif_carrier_off(netdev); netif_stop_queue(netdev); - if (!pci_channel_offline(adapter->pdev)) - ixgbe_reset(adapter); + ixgbe_reset(adapter); ixgbe_clean_all_tx_rings(adapter); ixgbe_clean_all_rx_rings(adapter); diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 63cd67b931e7..6797ed069f1f 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -71,18 +71,14 @@ static irqreturn_t netxen_intr(int irq, void *data); static irqreturn_t netxen_msi_intr(int irq, void *data); /* PCI Device ID Table */ -#define ENTRY(device) \ - {PCI_DEVICE(0x4040, (device)), \ - .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} - static struct pci_device_id netxen_pci_tbl[] __devinitdata = { - ENTRY(0x0001), - ENTRY(0x0002), - ENTRY(0x0003), - ENTRY(0x0004), - ENTRY(0x0005), - ENTRY(0x0024), - ENTRY(0x0025), + {PCI_DEVICE(0x4040, 0x0001), PCI_DEVICE_CLASS(0x020000, ~0)}, + {PCI_DEVICE(0x4040, 0x0002), PCI_DEVICE_CLASS(0x020000, ~0)}, + {PCI_DEVICE(0x4040, 0x0003), PCI_DEVICE_CLASS(0x020000, ~0)}, + {PCI_DEVICE(0x4040, 0x0004), PCI_DEVICE_CLASS(0x020000, ~0)}, + {PCI_DEVICE(0x4040, 0x0005), PCI_DEVICE_CLASS(0x020000, ~0)}, + {PCI_DEVICE(0x4040, 0x0024), PCI_DEVICE_CLASS(0x020000, ~0)}, + {PCI_DEVICE(0x4040, 0x0025), PCI_DEVICE_CLASS(0x020000, ~0)}, {0,} }; diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index 70d012e90dcf..ce95c5d168fe 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -525,14 +525,12 @@ static int axnet_open(struct net_device *dev) int ret; axnet_dev_t *info = PRIV(dev); struct pcmcia_device *link = info->p_dev; - unsigned int nic_base = dev->base_addr; DEBUG(2, "axnet_open('%s')\n", dev->name); if (!pcmcia_dev_present(link)) return -ENODEV; - outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); if (ret) return ret; diff --git a/trunk/drivers/net/pcmcia/pcnet_cs.c b/trunk/drivers/net/pcmcia/pcnet_cs.c index 2d4c4ad89b8d..fd8158a86f64 100644 --- a/trunk/drivers/net/pcmcia/pcnet_cs.c +++ b/trunk/drivers/net/pcmcia/pcnet_cs.c @@ -969,7 +969,6 @@ static int pcnet_open(struct net_device *dev) int ret; pcnet_dev_t *info = PRIV(dev); struct pcmcia_device *link = info->p_dev; - unsigned int nic_base = dev->base_addr; DEBUG(2, "pcnet_open('%s')\n", dev->name); @@ -977,8 +976,6 @@ static int pcnet_open(struct net_device *dev) return -ENODEV; set_misc_reg(dev); - - outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); if (ret) return ret; diff --git a/trunk/drivers/net/pppoe.c b/trunk/drivers/net/pppoe.c index fc6f4b8c64b3..bafb69b6f7cb 100644 --- a/trunk/drivers/net/pppoe.c +++ b/trunk/drivers/net/pppoe.c @@ -942,7 +942,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, m->msg_namelen = 0; if (skb) { - total_len = min_t(size_t, total_len, skb->len); + total_len = min(total_len, skb->len); error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); if (error == 0) error = total_len; diff --git a/trunk/drivers/net/qla3xxx.c b/trunk/drivers/net/qla3xxx.c index bccee68bd48a..b7f7b2227d56 100644 --- a/trunk/drivers/net/qla3xxx.c +++ b/trunk/drivers/net/qla3xxx.c @@ -3701,9 +3701,7 @@ static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset) printk(KERN_ERR PFX "%s: Driver up/down cycle failed, " "closing device\n",qdev->ndev->name); - rtnl_lock(); dev_close(qdev->ndev); - rtnl_unlock(); return -1; } return 0; diff --git a/trunk/drivers/net/r6040.c b/trunk/drivers/net/r6040.c index 504a48ff73c8..858b191517b3 100644 --- a/trunk/drivers/net/r6040.c +++ b/trunk/drivers/net/r6040.c @@ -273,7 +273,7 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, dma_addr_t mapping = desc_dma; while (size-- > 0) { - mapping += sizeof(*desc); + mapping += sizeof(sizeof(*desc)); desc->ndesc = cpu_to_le32(mapping); desc->vndescp = desc + 1; desc++; diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index ae7b697456b4..b5c1e663417d 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -2625,7 +2625,9 @@ static int fill_rx_buffers(struct ring_info *ring) rxdp1->Buffer0_ptr = pci_map_single (ring->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == + DMA_ERROR_CODE)) goto pci_map_failed; rxdp->Control_2 = @@ -2655,7 +2657,6 @@ static int fill_rx_buffers(struct ring_info *ring) skb->data = (void *) (unsigned long)tmp; skb_reset_tail_pointer(skb); - /* AK: check is wrong. 0 can be valid dma address */ if (!(rxdp3->Buffer0_ptr)) rxdp3->Buffer0_ptr = pci_map_single(ring->pdev, ba->ba_0, @@ -2664,7 +2665,8 @@ static int fill_rx_buffers(struct ring_info *ring) pci_dma_sync_single_for_device(ring->pdev, (dma_addr_t) rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) goto pci_map_failed; rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); @@ -2679,17 +2681,18 @@ static int fill_rx_buffers(struct ring_info *ring) (ring->pdev, skb->data, ring->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) goto pci_map_failed; - /* AK: check is wrong */ if (!rxdp3->Buffer1_ptr) rxdp3->Buffer1_ptr = pci_map_single(ring->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { pci_unmap_single (ring->pdev, (dma_addr_t)(unsigned long) @@ -4261,14 +4264,16 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, fifo->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) goto pci_map_failed; txdp->Host_Control = (unsigned long) skb; @@ -6879,8 +6884,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { goto memalloc_failed; + } rxdp->Host_Control = (unsigned long) (*skb); } } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { @@ -6906,12 +6913,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { goto memalloc_failed; + } rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); @@ -6923,7 +6933,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 1827b6686c98..4706f7f9acb6 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -75,6 +75,10 @@ static int debug_level = ERR_DBG; /* DEBUG message print. */ #define DBG_PRINT(dbg_level, args...) if(!(debug_levellock); - netif_carrier_off(dev); /* schedule a link state check */ phy_start(lp->phy_dev); @@ -1736,6 +1735,7 @@ tc35815_rx(struct net_device *dev) skb = lp->rx_skbs[cur_bd].skb; prefetch(skb->data); lp->rx_skbs[cur_bd].skb = NULL; + lp->fbl_count--; pci_unmap_single(lp->pci_dev, lp->rx_skbs[cur_bd].skb_dma, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); @@ -1791,7 +1791,6 @@ tc35815_rx(struct net_device *dev) #ifdef TC35815_USE_PACKEDBUFFER while (lp->fbl_curid != id) #else - lp->fbl_count--; while (lp->fbl_count < RX_BUF_NUM) #endif { @@ -2454,7 +2453,6 @@ static int tc35815_resume(struct pci_dev *pdev) return 0; pci_set_power_state(pdev, PCI_D0); tc35815_restart(dev); - netif_carrier_off(dev); if (lp->phy_dev) phy_start(lp->phy_dev); netif_device_attach(dev); diff --git a/trunk/drivers/net/wan/x25_asy.c b/trunk/drivers/net/wan/x25_asy.c index 069f8bb0a99f..249e18053d5f 100644 --- a/trunk/drivers/net/wan/x25_asy.c +++ b/trunk/drivers/net/wan/x25_asy.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "x25_asy.h" #include @@ -602,10 +601,8 @@ static void x25_asy_close_tty(struct tty_struct *tty) if (!sl || sl->magic != X25_ASY_MAGIC) return; - rtnl_lock(); if (sl->dev->flags & IFF_UP) dev_close(sl->dev); - rtnl_unlock(); tty->disc_data = NULL; sl->tty = NULL; diff --git a/trunk/drivers/net/wireless/b43/leds.c b/trunk/drivers/net/wireless/b43/leds.c index 76f4c7bad8b8..36a9c42df835 100644 --- a/trunk/drivers/net/wireless/b43/leds.c +++ b/trunk/drivers/net/wireless/b43/leds.c @@ -72,9 +72,6 @@ static void b43_led_brightness_set(struct led_classdev *led_dev, struct b43_wldev *dev = led->dev; bool radio_enabled; - if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) - return; - /* Checking the radio-enabled status here is slightly racy, * but we want to avoid the locking overhead and we don't care * whether the LED has the wrong state for a second. */ diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index a70827793086..fa4b0d8b74a2 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -2883,11 +2883,12 @@ static int b43_op_tx(struct ieee80211_hw *hw, if (unlikely(skb->len < 2 + 2 + 6)) { /* Too short, this can't be a valid frame. */ - goto drop_packet; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } B43_WARN_ON(skb_shinfo(skb)->nr_frags); if (unlikely(!dev)) - goto drop_packet; + return NETDEV_TX_BUSY; /* Transmissions on seperate queues can run concurrently. */ read_lock_irqsave(&wl->tx_lock, flags); @@ -2903,12 +2904,7 @@ static int b43_op_tx(struct ieee80211_hw *hw, read_unlock_irqrestore(&wl->tx_lock, flags); if (unlikely(err)) - goto drop_packet; - return NETDEV_TX_OK; - -drop_packet: - /* We can not transmit this packet. Drop it. */ - dev_kfree_skb_any(skb); + return NETDEV_TX_BUSY; return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/wireless/b43legacy/dma.c b/trunk/drivers/net/wireless/b43legacy/dma.c index 93ddc1cbcc8b..c990f87b107a 100644 --- a/trunk/drivers/net/wireless/b43legacy/dma.c +++ b/trunk/drivers/net/wireless/b43legacy/dma.c @@ -876,7 +876,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, if (!ring) goto out; ring->type = type; - ring->dev = dev; nr_slots = B43legacy_RXRING_SLOTS; if (for_tx) @@ -923,6 +922,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, DMA_TO_DEVICE); } + ring->dev = dev; ring->nr_slots = nr_slots; ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); ring->index = controller_index; diff --git a/trunk/drivers/net/wireless/b43legacy/main.c b/trunk/drivers/net/wireless/b43legacy/main.c index 3e612d0a13e8..204077c13870 100644 --- a/trunk/drivers/net/wireless/b43legacy/main.c +++ b/trunk/drivers/net/wireless/b43legacy/main.c @@ -2378,10 +2378,8 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw, } else err = b43legacy_dma_tx(dev, skb, ctl); out: - if (unlikely(err)) { - /* Drop the packet. */ - dev_kfree_skb_any(skb); - } + if (unlikely(err)) + return NETDEV_TX_BUSY; return NETDEV_TX_OK; } diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c b/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c index 020f450e9dba..4fd73809602e 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -64,7 +64,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, int hdrlen, phdrlen, head_need, tail_need; u16 fc; int prism_header, ret; - struct ieee80211_hdr_4addr *fhdr; + struct ieee80211_hdr_4addr *hdr; iface = netdev_priv(dev); local = iface->local; @@ -83,8 +83,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, phdrlen = 0; } - fhdr = (struct ieee80211_hdr_4addr *) skb->data; - fc = le16_to_cpu(fhdr->frame_ctl); + hdr = (struct ieee80211_hdr_4addr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) { printk(KERN_DEBUG "%s: dropped management frame with header " @@ -551,7 +551,7 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr, hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff || hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { /* RA (or BSSID) is not ours - drop */ - PDEBUG(DEBUG_EXTRA2, "%s: received WDS frame with " + PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with " "not own or broadcast %s=%s\n", local->dev->name, fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID", diff --git a/trunk/drivers/net/wireless/hostap/hostap_ap.c b/trunk/drivers/net/wireless/hostap/hostap_ap.c index ab981afd481d..0acd9589c48c 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ap.c +++ b/trunk/drivers/net/wireless/hostap/hostap_ap.c @@ -1930,7 +1930,7 @@ static void handle_pspoll(local_info_t *local, PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n"); return; } - aid &= ~(BIT(15) | BIT(14)); + aid &= ~BIT(15) & ~BIT(14); if (aid == 0 || aid > MAX_AID_TABLE_SIZE) { PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid); return; diff --git a/trunk/drivers/net/wireless/hostap/hostap_cs.c b/trunk/drivers/net/wireless/hostap/hostap_cs.c index 80039a0ae027..ed4317a17cbb 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_cs.c +++ b/trunk/drivers/net/wireless/hostap/hostap_cs.c @@ -533,10 +533,10 @@ static void prism2_detach(struct pcmcia_device *link) do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) #define CFG_CHECK2(fn, retf) \ -do { int _ret = (retf); \ -if (_ret != 0) { \ - PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \ - cs_error(link, fn, _ret); \ +do { int ret = (retf); \ +if (ret != 0) { \ + PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \ + cs_error(link, fn, ret); \ goto next_entry; \ } \ } while (0) diff --git a/trunk/drivers/net/wireless/hostap/hostap_hw.c b/trunk/drivers/net/wireless/hostap/hostap_hw.c index 936f52e3d95c..cdf90c40f11b 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_hw.c +++ b/trunk/drivers/net/wireless/hostap/hostap_hw.c @@ -2835,7 +2835,7 @@ static void hostap_passive_scan(unsigned long data) { local_info_t *local = (local_info_t *) data; struct net_device *dev = local->dev; - u16 chan; + u16 channel; if (local->passive_scan_interval <= 0) return; @@ -2872,11 +2872,11 @@ static void hostap_passive_scan(unsigned long data) printk(KERN_DEBUG "%s: passive scan channel %d\n", dev->name, local->passive_scan_channel); - chan = local->passive_scan_channel; + channel = local->passive_scan_channel; local->passive_scan_state = PASSIVE_SCAN_WAIT; local->passive_scan_timer.expires = jiffies + HZ / 10; } else { - chan = local->channel; + channel = local->channel; local->passive_scan_state = PASSIVE_SCAN_LISTEN; local->passive_scan_timer.expires = jiffies + local->passive_scan_interval * HZ; @@ -2884,9 +2884,9 @@ static void hostap_passive_scan(unsigned long data) if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST | (HFA384X_TEST_CHANGE_CHANNEL << 8), - chan, NULL, 0)) + channel, NULL, 0)) printk(KERN_ERR "%s: passive scan channel set %d " - "failed\n", dev->name, chan); + "failed\n", dev->name, channel); add_timer(&local->passive_scan_timer); } diff --git a/trunk/drivers/net/wireless/hostap/hostap_main.c b/trunk/drivers/net/wireless/hostap/hostap_main.c index a38e85f334df..f7aec9309d04 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_main.c +++ b/trunk/drivers/net/wireless/hostap/hostap_main.c @@ -594,8 +594,7 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) } -static int hostap_80211_header_parse(const struct sk_buff *skb, - unsigned char *haddr) +int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr) { struct hostap_interface *iface = netdev_priv(skb->dev); local_info_t *local = iface->local; @@ -858,6 +857,7 @@ const struct header_ops hostap_80211_ops = { .rebuild = eth_rebuild_header, .cache = eth_header_cache, .cache_update = eth_header_cache_update, + .parse = hostap_80211_header_parse, }; EXPORT_SYMBOL(hostap_80211_ops); @@ -1150,6 +1150,7 @@ EXPORT_SYMBOL(hostap_set_roaming); EXPORT_SYMBOL(hostap_set_auth_algs); EXPORT_SYMBOL(hostap_dump_rx_header); EXPORT_SYMBOL(hostap_dump_tx_header); +EXPORT_SYMBOL(hostap_80211_header_parse); EXPORT_SYMBOL(hostap_80211_get_hdrlen); EXPORT_SYMBOL(hostap_get_stats); EXPORT_SYMBOL(hostap_setup_dev); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index b1b3c523185d..13925b627e3b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2227,10 +2227,7 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv) } IWL_DEBUG_INFO("Starting scan...\n"); - if (priv->cfg->sku & IWL_SKU_G) - priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); - if (priv->cfg->sku & IWL_SKU_A) - priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); + priv->scan_bands = 2; set_bit(STATUS_SCANNING, &priv->status); priv->scan_start = jiffies; priv->scan_pass_start = priv->scan_start; @@ -3355,18 +3352,13 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, cancel_delayed_work(&priv->scan_check); IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", - (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? - "2.4" : "5.2", + (priv->scan_bands == 2) ? "2.4" : "5.2", jiffies_to_msecs(elapsed_jiffies (priv->scan_pass_start, jiffies))); - /* Remove this scanned band from the list of pending - * bands to scan, band G precedes A in order of scanning - * as seen in iwl3945_bg_request_scan */ - if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) - priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); - else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) - priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); + /* Remove this scanned band from the list + * of pending bands to scan */ + priv->scan_bands--; /* If a request to abort was given, or the scan did not succeed * then we reset the scan state machine and terminate, @@ -4980,7 +4972,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", + IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", scan_ch->channel); continue; } @@ -6323,16 +6315,21 @@ static void iwl3945_bg_request_scan(struct work_struct *data) /* flags + rate selection */ - if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { + switch (priv->scan_bands) { + case 2: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; scan->tx_cmd.rate = IWL_RATE_1M_PLCP; scan->good_CRC_th = 0; band = IEEE80211_BAND_2GHZ; - } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { + break; + + case 1: scan->tx_cmd.rate = IWL_RATE_6M_PLCP; scan->good_CRC_th = IWL_GOOD_CRC_TH; band = IEEE80211_BAND_5GHZ; - } else { + break; + + default: IWL_WARNING("Invalid scan band count\n"); goto done; } @@ -6773,7 +6770,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co ch_info = iwl3945_get_channel_info(priv, conf->channel->band, conf->channel->hw_value); if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n", + IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", conf->channel->hw_value, conf->channel->band); IWL_DEBUG_MAC80211("leave - invalid channel\n"); spin_unlock_irqrestore(&priv->lock, flags); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c index 5ed16ce78468..883b42f7e998 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1774,10 +1774,7 @@ static int iwl4965_scan_initiate(struct iwl_priv *priv) } IWL_DEBUG_INFO("Starting scan...\n"); - if (priv->cfg->sku & IWL_SKU_G) - priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); - if (priv->cfg->sku & IWL_SKU_A) - priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); + priv->scan_bands = 2; set_bit(STATUS_SCANNING, &priv->status); priv->scan_start = jiffies; priv->scan_pass_start = priv->scan_start; @@ -3026,9 +3023,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); if (index != -1) { -#ifdef CONFIG_IWL4965_HT int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); - +#ifdef CONFIG_IWL4965_HT if (tid != MAX_TID_COUNT) priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && @@ -3280,18 +3276,13 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, cancel_delayed_work(&priv->scan_check); IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", - (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? - "2.4" : "5.2", + (priv->scan_bands == 2) ? "2.4" : "5.2", jiffies_to_msecs(elapsed_jiffies (priv->scan_pass_start, jiffies))); - /* Remove this scanned band from the list of pending - * bands to scan, band G precedes A in order of scanning - * as seen in iwl_bg_request_scan */ - if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) - priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); - else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) - priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); + /* Remove this scanned band from the list + * of pending bands to scan */ + priv->scan_bands--; /* If a request to abort was given, or the scan did not succeed * then we reset the scan state machine and terminate, @@ -3301,7 +3292,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, clear_bit(STATUS_SCAN_ABORTING, &priv->status); } else { /* If there are more bands on this scan pass reschedule */ - if (priv->scan_bands) + if (priv->scan_bands > 0) goto reschedule; } @@ -4644,9 +4635,10 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); - ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); + ch_info = iwl_get_channel_info(priv, band, + scan_ch->channel); if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", + IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", scan_ch->channel); continue; } @@ -5838,7 +5830,8 @@ static void iwl4965_bg_request_scan(struct work_struct *data) scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { + switch (priv->scan_bands) { + case 2: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; scan->tx_cmd.rate_n_flags = iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, @@ -5846,13 +5839,17 @@ static void iwl4965_bg_request_scan(struct work_struct *data) scan->good_CRC_th = 0; band = IEEE80211_BAND_2GHZ; - } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { + break; + + case 1: scan->tx_cmd.rate_n_flags = iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, RATE_MCS_ANT_B_MSK); scan->good_CRC_th = IWL_GOOD_CRC_TH; band = IEEE80211_BAND_5GHZ; - } else { + break; + + default: IWL_WARNING("Invalid scan band count\n"); goto done; } diff --git a/trunk/drivers/net/wireless/prism54/islpci_eth.c b/trunk/drivers/net/wireless/prism54/islpci_eth.c index e43bae97ed8f..762e85bef55d 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_eth.c +++ b/trunk/drivers/net/wireless/prism54/islpci_eth.c @@ -290,7 +290,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb) avs->version = cpu_to_be32(P80211CAPTURE_VERSION); avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); - avs->mactime = cpu_to_be64(clock); + avs->mactime = cpu_to_be64(le64_to_cpu(clock)); avs->hosttime = cpu_to_be64(jiffies); avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */ avs->channel = cpu_to_be32(channel_of_freq(freq)); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 61e59c17a60a..fdbd0ef2be4b 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -138,8 +138,11 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, * Wait until the BBP becomes ready. */ reg = rt2500usb_bbp_check(rt2x00dev); - if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) - goto exit_fail; + if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { + ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); + mutex_unlock(&rt2x00dev->usb_cache_mutex); + return; + } /* * Write the data into the BBP. @@ -152,13 +155,6 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); mutex_unlock(&rt2x00dev->usb_cache_mutex); - - return; - -exit_fail: - mutex_unlock(&rt2x00dev->usb_cache_mutex); - - ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); } static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, @@ -172,8 +168,10 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, * Wait until the BBP becomes ready. */ reg = rt2500usb_bbp_check(rt2x00dev); - if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) - goto exit_fail; + if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { + ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); + return; + } /* * Write the request into the BBP. @@ -188,21 +186,17 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, * Wait until the BBP becomes ready. */ reg = rt2500usb_bbp_check(rt2x00dev); - if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) - goto exit_fail; + if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { + ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); + *value = 0xff; + mutex_unlock(&rt2x00dev->usb_cache_mutex); + return; + } rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); mutex_unlock(&rt2x00dev->usb_cache_mutex); - - return; - -exit_fail: - mutex_unlock(&rt2x00dev->usb_cache_mutex); - - ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); - *value = 0xff; } static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00.h b/trunk/drivers/net/wireless/rt2x00/rt2x00.h index b4bf1e09cf9a..611d98320593 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00.h @@ -821,7 +821,6 @@ struct rt2x00_dev { /* * Scheduled work. */ - struct workqueue_struct *workqueue; struct work_struct intf_work; struct work_struct filter_work; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index c997d4f28ab3..2673d568bcac 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -75,7 +75,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) rt2x00lib_reset_link_tuner(rt2x00dev); - queue_delayed_work(rt2x00dev->workqueue, + queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, LINK_TUNE_INTERVAL); } @@ -136,6 +136,14 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) if (!__test_and_clear_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) return; + /* + * Stop all scheduled work. + */ + if (work_pending(&rt2x00dev->intf_work)) + cancel_work_sync(&rt2x00dev->intf_work); + if (work_pending(&rt2x00dev->filter_work)) + cancel_work_sync(&rt2x00dev->filter_work); + /* * Stop the TX queues. */ @@ -390,8 +398,8 @@ static void rt2x00lib_link_tuner(struct work_struct *work) * Increase tuner counter, and reschedule the next link tuner run. */ rt2x00dev->link.count++; - queue_delayed_work(rt2x00dev->workqueue, - &rt2x00dev->link.work, LINK_TUNE_INTERVAL); + queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, + LINK_TUNE_INTERVAL); } static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) @@ -425,15 +433,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, spin_unlock(&intf->lock); - /* - * It is possible the radio was disabled while the work had been - * scheduled. If that happens we should return here immediately, - * note that in the spinlock protected area above the delayed_flags - * have been cleared correctly. - */ - if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) - return; - if (delayed_flags & DELAYED_UPDATE_BEACON) { skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, @@ -442,7 +441,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, } if (delayed_flags & DELAYED_CONFIG_ERP) - rt2x00lib_config_erp(rt2x00dev, intf, &conf); + rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); if (delayed_flags & DELAYED_LED_ASSOC) rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); @@ -488,7 +487,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) rt2x00lib_beacondone_iter, rt2x00dev); - queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); + queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); } EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); @@ -1131,10 +1130,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) /* * Initialize configuration work. */ - rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib"); - if (!rt2x00dev->workqueue) - goto exit; - INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); @@ -1194,13 +1189,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) rt2x00rfkill_free(rt2x00dev); rt2x00leds_unregister(rt2x00dev); - /* - * Stop all queued work. Note that most tasks will already be halted - * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize(). - */ - flush_workqueue(rt2x00dev->workqueue); - destroy_workqueue(rt2x00dev->workqueue); - /* * Free ieee80211_hw memory. */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c index 9cb023edd2e9..87e280a21971 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -428,7 +428,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); else - queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work); + queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); } EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); @@ -509,7 +509,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); if (delayed) { intf->delayed_flags |= delayed; - queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); + queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); } spin_unlock(&intf->lock); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 83cc0147f698..fff8386e816b 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -134,8 +134,11 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, * Wait until the BBP becomes ready. */ reg = rt73usb_bbp_check(rt2x00dev); - if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) - goto exit_fail; + if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { + ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); + mutex_unlock(&rt2x00dev->usb_cache_mutex); + return; + } /* * Write the data into the BBP. @@ -148,13 +151,6 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); mutex_unlock(&rt2x00dev->usb_cache_mutex); - - return; - -exit_fail: - mutex_unlock(&rt2x00dev->usb_cache_mutex); - - ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); } static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, @@ -168,8 +164,11 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, * Wait until the BBP becomes ready. */ reg = rt73usb_bbp_check(rt2x00dev); - if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) - goto exit_fail; + if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { + ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); + mutex_unlock(&rt2x00dev->usb_cache_mutex); + return; + } /* * Write the request into the BBP. @@ -185,19 +184,14 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, * Wait until the BBP becomes ready. */ reg = rt73usb_bbp_check(rt2x00dev); - if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) - goto exit_fail; + if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { + ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); + *value = 0xff; + return; + } *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); mutex_unlock(&rt2x00dev->usb_cache_mutex); - - return; - -exit_fail: - mutex_unlock(&rt2x00dev->usb_cache_mutex); - - ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); - *value = 0xff; } static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, diff --git a/trunk/drivers/pci/access.c b/trunk/drivers/pci/access.c index 39bb96b413ef..ec8f7002b09d 100644 --- a/trunk/drivers/pci/access.c +++ b/trunk/drivers/pci/access.c @@ -178,7 +178,8 @@ static int pci_vpd_pci22_read(struct pci_dev *dev, int pos, int size, int ret; int begin, end, i; - if (pos < 0 || pos > vpd->base.len || size > vpd->base.len - pos) + if (pos < 0 || pos > PCI_VPD_PCI22_SIZE || + size > PCI_VPD_PCI22_SIZE - pos) return -EINVAL; if (size == 0) return 0; @@ -222,8 +223,8 @@ static int pci_vpd_pci22_write(struct pci_dev *dev, int pos, int size, u32 val; int ret; - if (pos < 0 || pos > vpd->base.len || pos & 3 || - size > vpd->base.len - pos || size < 4) + if (pos < 0 || pos > PCI_VPD_PCI22_SIZE || pos & 3 || + size > PCI_VPD_PCI22_SIZE - pos || size < 4) return -EINVAL; val = (u8) *buf++; @@ -254,6 +255,11 @@ static int pci_vpd_pci22_write(struct pci_dev *dev, int pos, int size, return 4; } +static int pci_vpd_pci22_get_size(struct pci_dev *dev) +{ + return PCI_VPD_PCI22_SIZE; +} + static void pci_vpd_pci22_release(struct pci_dev *dev) { kfree(container_of(dev->vpd, struct pci_vpd_pci22, base)); @@ -262,6 +268,7 @@ static void pci_vpd_pci22_release(struct pci_dev *dev) static struct pci_vpd_ops pci_vpd_pci22_ops = { .read = pci_vpd_pci22_read, .write = pci_vpd_pci22_write, + .get_size = pci_vpd_pci22_get_size, .release = pci_vpd_pci22_release, }; @@ -277,7 +284,6 @@ int pci_vpd_pci22_init(struct pci_dev *dev) if (!vpd) return -ENOMEM; - vpd->base.len = PCI_VPD_PCI22_SIZE; vpd->base.ops = &pci_vpd_pci22_ops; spin_lock_init(&vpd->lock); vpd->cap = cap; diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 91156f85a926..648596d469f6 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -700,10 +700,9 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, cleanup_p2p_bridge, NULL, NULL); - bridge = acpiphp_handle_to_bridge(handle); - if (bridge) - cleanup_bridge(bridge); - + if (!(bridge = acpiphp_handle_to_bridge(handle))) + return AE_OK; + cleanup_bridge(bridge); return AE_OK; } @@ -716,19 +715,9 @@ static void remove_bridge(acpi_handle handle) acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, cleanup_p2p_bridge, NULL, NULL); - /* - * On root bridges with hotplug slots directly underneath (ie, - * no p2p bridge inbetween), we call cleanup_bridge(). - * - * The else clause cleans up root bridges that either had no - * hotplug slots at all, or had a p2p bridge underneath. - */ bridge = acpiphp_handle_to_bridge(handle); if (bridge) cleanup_bridge(bridge); - else - acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_bridge); } static struct pci_dev * get_apic_pci_info(acpi_handle handle) diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index 9c718583a237..6f3c7446c329 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -736,9 +736,9 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) attr = kzalloc(sizeof(*attr), GFP_ATOMIC); if (attr) { pdev->vpd->attr = attr; - attr->size = pdev->vpd->len; + attr->size = pdev->vpd->ops->get_size(pdev); attr->attr.name = "vpd"; - attr->attr.mode = S_IRUSR | S_IWUSR; + attr->attr.mode = S_IRUGO | S_IWUSR; attr->read = pci_read_vpd; attr->write = pci_write_vpd; retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 00408c97e5fc..0a497c1b4227 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -21,11 +21,11 @@ extern int pci_user_write_config_dword(struct pci_dev *dev, int where, u32 val); struct pci_vpd_ops { int (*read)(struct pci_dev *dev, int pos, int size, char *buf); int (*write)(struct pci_dev *dev, int pos, int size, const char *buf); + int (*get_size)(struct pci_dev *dev); void (*release)(struct pci_dev *dev); }; struct pci_vpd { - unsigned int len; struct pci_vpd_ops *ops; struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ }; diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index a3497dc6ebcf..dabb563f51d9 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -1670,48 +1670,6 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); -/* - * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the - * VPD end tag will hang the device. This problem was initially - * observed when a vpd entry was created in sysfs - * ('/sys/bus/pci/devices//vpd'). A read to this sysfs entry - * will dump 32k of data. Reading a full 32k will cause an access - * beyond the VPD end tag causing the device to hang. Once the device - * is hung, the bnx2 driver will not be able to reset the device. - * We believe that it is legal to read beyond the end tag and - * therefore the solution is to limit the read/write length. - */ -static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev) -{ - /* Only disable the VPD capability for 5706, 5708, and 5709 rev. A */ - if ((dev->device == PCI_DEVICE_ID_NX2_5706) || - (dev->device == PCI_DEVICE_ID_NX2_5708) || - ((dev->device == PCI_DEVICE_ID_NX2_5709) && - (dev->revision & 0xf0) == 0x0)) { - if (dev->vpd) - dev->vpd->len = 0x80; - } -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, - PCI_DEVICE_ID_NX2_5706, - quirk_brcm_570x_limit_vpd); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, - PCI_DEVICE_ID_NX2_5706S, - quirk_brcm_570x_limit_vpd); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, - PCI_DEVICE_ID_NX2_5708, - quirk_brcm_570x_limit_vpd); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, - PCI_DEVICE_ID_NX2_5708S, - quirk_brcm_570x_limit_vpd); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, - PCI_DEVICE_ID_NX2_5709, - quirk_brcm_570x_limit_vpd); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, - PCI_DEVICE_ID_NX2_5709S, - quirk_brcm_570x_limit_vpd); - #ifdef CONFIG_PCI_MSI /* Some chipsets do not support MSI. We cannot easily rely on setting * PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually diff --git a/trunk/drivers/pcmcia/omap_cf.c b/trunk/drivers/pcmcia/omap_cf.c index 569b746b5731..46314b420765 100644 --- a/trunk/drivers/pcmcia/omap_cf.c +++ b/trunk/drivers/pcmcia/omap_cf.c @@ -38,19 +38,19 @@ #define CF_BASE 0xfffe2800 /* status; read after IRQ */ -#define CF_STATUS (CF_BASE + 0x00) +#define CF_STATUS_REG __REG16(CF_BASE + 0x00) # define CF_STATUS_BAD_READ (1 << 2) # define CF_STATUS_BAD_WRITE (1 << 1) # define CF_STATUS_CARD_DETECT (1 << 0) /* which chipselect (CS0..CS3) is used for CF (active low) */ -#define CF_CFG (CF_BASE + 0x02) +#define CF_CFG_REG __REG16(CF_BASE + 0x02) /* card reset */ -#define CF_CONTROL (CF_BASE + 0x04) +#define CF_CONTROL_REG __REG16(CF_BASE + 0x04) # define CF_CONTROL_RESET (1 << 0) -#define omap_cf_present() (!(omap_readw(CF_STATUS) & CF_STATUS_CARD_DETECT)) +#define omap_cf_present() (!(CF_STATUS_REG & CF_STATUS_CARD_DETECT)) /*--------------------------------------------------------------------------*/ @@ -139,11 +139,11 @@ omap_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) return -EINVAL; } - control = omap_readw(CF_CONTROL); + control = CF_CONTROL_REG; if (s->flags & SS_RESET) - omap_writew(CF_CONTROL_RESET, CF_CONTROL); + CF_CONTROL_REG = CF_CONTROL_RESET; else - omap_writew(0, CF_CONTROL); + CF_CONTROL_REG = 0; pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); @@ -270,7 +270,7 @@ static int __init omap_cf_probe(struct platform_device *pdev) omap_cfg_reg(V10_1610_CF_IREQ); omap_cfg_reg(W10_1610_CF_RESET); - omap_writew(~(1 << seg), CF_CFG); + CF_CFG_REG = ~(1 << seg); pr_info("%s: cs%d on irq %d\n", driver_name, seg, irq); @@ -279,15 +279,14 @@ static int __init omap_cf_probe(struct platform_device *pdev) * CF/PCMCIA variants... */ pr_debug("%s: cs%d, previous ccs %08x acs %08x\n", driver_name, - seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg))); - omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */ - omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */ + seg, EMIFS_CCS(seg), EMIFS_ACS(seg)); + EMIFS_CCS(seg) = 0x0004a1b3; /* synch mode 4 etc */ + EMIFS_ACS(seg) = 0x00000000; /* OE hold/setup */ /* CF uses armxor_ck, which is "always" available */ pr_debug("%s: sts %04x cfg %04x control %04x %s\n", driver_name, - omap_readw(CF_STATUS), omap_readw(CF_CFG), - omap_readw(CF_CONTROL), + CF_STATUS_REG, CF_CFG_REG, CF_CONTROL_REG, omap_cf_present() ? "present" : "(not present)"); cf->socket.owner = THIS_MODULE; diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index 67421b0d3a7b..82f62d25f921 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -331,14 +331,14 @@ static int sa1100_rtc_probe(struct platform_device *pdev) RCNR = 0; } - device_init_wakeup(&pdev->dev, 1); - rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return PTR_ERR(rtc); + device_init_wakeup(&pdev->dev, 1); + platform_set_drvdata(pdev, rtc); return 0; diff --git a/trunk/drivers/scsi/esp_scsi.c b/trunk/drivers/scsi/esp_scsi.c index 59fbef08d690..a0b6d414953d 100644 --- a/trunk/drivers/scsi/esp_scsi.c +++ b/trunk/drivers/scsi/esp_scsi.c @@ -2359,24 +2359,6 @@ void scsi_esp_unregister(struct esp *esp) } EXPORT_SYMBOL(scsi_esp_unregister); -static int esp_target_alloc(struct scsi_target *starget) -{ - struct esp *esp = shost_priv(dev_to_shost(&starget->dev)); - struct esp_target_data *tp = &esp->target[starget->id]; - - tp->starget = starget; - - return 0; -} - -static void esp_target_destroy(struct scsi_target *starget) -{ - struct esp *esp = shost_priv(dev_to_shost(&starget->dev)); - struct esp_target_data *tp = &esp->target[starget->id]; - - tp->starget = NULL; -} - static int esp_slave_alloc(struct scsi_device *dev) { struct esp *esp = shost_priv(dev->host); @@ -2388,6 +2370,8 @@ static int esp_slave_alloc(struct scsi_device *dev) return -ENOMEM; dev->hostdata = lp; + tp->starget = dev->sdev_target; + spi_min_period(tp->starget) = esp->min_period; spi_max_offset(tp->starget) = 15; @@ -2624,8 +2608,6 @@ struct scsi_host_template scsi_esp_template = { .name = "esp", .info = esp_info, .queuecommand = esp_queuecommand, - .target_alloc = esp_target_alloc, - .target_destroy = esp_target_destroy, .slave_alloc = esp_slave_alloc, .slave_configure = esp_slave_configure, .slave_destroy = esp_slave_destroy, diff --git a/trunk/drivers/scsi/ses.c b/trunk/drivers/scsi/ses.c index 0fe031f003e7..45df83b9d847 100644 --- a/trunk/drivers/scsi/ses.c +++ b/trunk/drivers/scsi/ses.c @@ -61,7 +61,7 @@ static int ses_probe(struct device *dev) return err; } -#define SES_TIMEOUT (30 * HZ) +#define SES_TIMEOUT 30 #define SES_RETRIES 3 static int ses_recv_diag(struct scsi_device *sdev, int page_code, diff --git a/trunk/drivers/thermal/Kconfig b/trunk/drivers/thermal/Kconfig index a86e952ed4ca..4b628526df09 100644 --- a/trunk/drivers/thermal/Kconfig +++ b/trunk/drivers/thermal/Kconfig @@ -12,12 +12,3 @@ menuconfig THERMAL cooling devices. All platforms with ACPI thermal support can use this driver. If you want this support, you should say Y or M here. - -config THERMAL_HWMON - bool "Hardware monitoring support" - depends on HWMON=y || HWMON=THERMAL - help - The generic thermal sysfs driver's hardware monitoring support - requires a 2.10.7/3.0.2 or later lm-sensors userspace. - - Say Y if your user-space is new enough. diff --git a/trunk/drivers/thermal/thermal_sys.c b/trunk/drivers/thermal/thermal_sys.c index fe07462d5947..6098787341f3 100644 --- a/trunk/drivers/thermal/thermal_sys.c +++ b/trunk/drivers/thermal/thermal_sys.c @@ -295,8 +295,8 @@ thermal_cooling_device_trip_point_show(struct device *dev, /* Device management */ -#if defined(CONFIG_THERMAL_HWMON) - +#if defined(CONFIG_HWMON) || \ + (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE)) /* hwmon sys I/F */ #include static LIST_HEAD(thermal_hwmon_list); diff --git a/trunk/drivers/usb/gadget/omap_udc.c b/trunk/drivers/usb/gadget/omap_udc.c index 03a7f49d207d..881d74c3d964 100644 --- a/trunk/drivers/usb/gadget/omap_udc.c +++ b/trunk/drivers/usb/gadget/omap_udc.c @@ -135,17 +135,13 @@ static void use_ep(struct omap_ep *ep, u16 select) if (ep->bEndpointAddress & USB_DIR_IN) num |= UDC_EP_DIR; - omap_writew(num | select, UDC_EP_NUM); + UDC_EP_NUM_REG = num | select; /* when select, MUST deselect later !! */ } static inline void deselect_ep(void) { - u16 w; - - w = omap_readw(UDC_EP_NUM); - w &= ~UDC_EP_SEL; - omap_writew(w, UDC_EP_NUM); + UDC_EP_NUM_REG &= ~UDC_EP_SEL; /* 6 wait states before TX will happen */ } @@ -220,7 +216,7 @@ static int omap_ep_enable(struct usb_ep *_ep, ep->has_dma = 0; ep->lch = -1; use_ep(ep, UDC_EP_SEL); - omap_writew(udc->clr_halt, UDC_CTRL); + UDC_CTRL_REG = udc->clr_halt; ep->ackwait = 0; deselect_ep(); @@ -236,7 +232,7 @@ static int omap_ep_enable(struct usb_ep *_ep, if (desc->bmAttributes != USB_ENDPOINT_XFER_ISOC && !ep->has_dma && !(ep->bEndpointAddress & USB_DIR_IN)) { - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1 + ep->double_buf; } @@ -263,7 +259,7 @@ static int omap_ep_disable(struct usb_ep *_ep) nuke (ep, -ESHUTDOWN); ep->ep.maxpacket = ep->maxpacket; ep->has_dma = 0; - omap_writew(UDC_SET_HALT, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_HALT; list_del_init(&ep->iso); del_timer(&ep->timer); @@ -364,13 +360,13 @@ write_packet(u8 *buf, struct omap_req *req, unsigned max) if (likely((((int)buf) & 1) == 0)) { wp = (u16 *)buf; while (max >= 2) { - omap_writew(*wp++, UDC_DATA); + UDC_DATA_REG = *wp++; max -= 2; } buf = (u8 *)wp; } while (max--) - omap_writeb(*buf++, UDC_DATA); + *(volatile u8 *)&UDC_DATA_REG = *buf++; return len; } @@ -389,13 +385,13 @@ static int write_fifo(struct omap_ep *ep, struct omap_req *req) prefetch(buf); /* PIO-IN isn't double buffered except for iso */ - ep_stat = omap_readw(UDC_STAT_FLG); + ep_stat = UDC_STAT_FLG_REG; if (ep_stat & UDC_FIFO_UNWRITABLE) return 0; count = ep->ep.maxpacket; count = write_packet(buf, req, count); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1; /* last packet is often short (sometimes a zlp) */ @@ -429,13 +425,13 @@ read_packet(u8 *buf, struct omap_req *req, unsigned avail) if (likely((((int)buf) & 1) == 0)) { wp = (u16 *)buf; while (avail >= 2) { - *wp++ = omap_readw(UDC_DATA); + *wp++ = UDC_DATA_REG; avail -= 2; } buf = (u8 *)wp; } while (avail--) - *buf++ = omap_readb(UDC_DATA); + *buf++ = *(volatile u8 *)&UDC_DATA_REG; return len; } @@ -450,7 +446,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) prefetchw(buf); for (;;) { - u16 ep_stat = omap_readw(UDC_STAT_FLG); + u16 ep_stat = UDC_STAT_FLG_REG; is_last = 0; if (ep_stat & FIFO_EMPTY) { @@ -464,7 +460,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) if (ep_stat & UDC_FIFO_FULL) avail = ep->ep.maxpacket; else { - avail = omap_readw(UDC_RXFSTAT); + avail = UDC_RXFSTAT_REG; ep->fnf = ep->double_buf; } count = read_packet(buf, req, avail); @@ -477,7 +473,7 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) req->req.status = -EOVERFLOW; avail -= count; while (avail--) - omap_readw(UDC_DATA); + (void) *(volatile u8 *)&UDC_DATA_REG; } } else if (req->req.length == req->req.actual) is_last = 1; @@ -495,6 +491,32 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) /*-------------------------------------------------------------------------*/ +static inline dma_addr_t dma_csac(unsigned lch) +{ + dma_addr_t csac; + + /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is + * read before the DMA controller finished disabling the channel. + */ + csac = OMAP_DMA_CSAC_REG(lch); + if (csac == 0) + csac = OMAP_DMA_CSAC_REG(lch); + return csac; +} + +static inline dma_addr_t dma_cdac(unsigned lch) +{ + dma_addr_t cdac; + + /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is + * read before the DMA controller finished disabling the channel. + */ + cdac = OMAP_DMA_CDAC_REG(lch); + if (cdac == 0) + cdac = OMAP_DMA_CDAC_REG(lch); + return cdac; +} + static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) { dma_addr_t end; @@ -505,7 +527,7 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) if (cpu_is_omap15xx()) return 0; - end = omap_get_dma_src_pos(ep->lch); + end = dma_csac(ep->lch); if (end == ep->dma_counter) return 0; @@ -515,11 +537,15 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) return end - start; } +#define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ + ? OMAP_DMA_CSAC_REG(x) /* really: CPC */ \ + : dma_cdac(x)) + static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) { dma_addr_t end; - end = omap_get_dma_dst_pos(ep->lch); + end = DMA_DEST_LAST(ep->lch); if (end == ep->dma_counter) return 0; @@ -539,7 +565,7 @@ static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) static void next_in_dma(struct omap_ep *ep, struct omap_req *req) { - u16 txdma_ctrl, w; + u16 txdma_ctrl; unsigned length = req->req.length - req->req.actual; const int sync_mode = cpu_is_omap15xx() ? OMAP_DMA_SYNC_FRAME @@ -570,18 +596,14 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) 0, 0); omap_start_dma(ep->lch); - ep->dma_counter = omap_get_dma_src_pos(ep->lch); - w = omap_readw(UDC_DMA_IRQ_EN); - w |= UDC_TX_DONE_IE(ep->dma_channel); - omap_writew(w, UDC_DMA_IRQ_EN); - omap_writew(UDC_TXN_START | txdma_ctrl, UDC_TXDMA(ep->dma_channel)); + ep->dma_counter = dma_csac(ep->lch); + UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel); + UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl; req->dma_bytes = length; } static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status) { - u16 w; - if (status == 0) { req->req.actual += req->dma_bytes; @@ -598,9 +620,7 @@ static void finish_in_dma(struct omap_ep *ep, struct omap_req *req, int status) /* tx completion */ omap_stop_dma(ep->lch); - w = omap_readw(UDC_DMA_IRQ_EN); - w &= ~UDC_TX_DONE_IE(ep->dma_channel); - omap_writew(w, UDC_DMA_IRQ_EN); + UDC_DMA_IRQ_EN_REG &= ~UDC_TX_DONE_IE(ep->dma_channel); done(ep, req, status); } @@ -608,7 +628,6 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) { unsigned packets = req->req.length - req->req.actual; int dma_trigger = 0; - u16 w; if (cpu_is_omap24xx()) dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel); @@ -635,14 +654,12 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, 0, 0); - ep->dma_counter = omap_get_dma_dst_pos(ep->lch); + ep->dma_counter = DMA_DEST_LAST(ep->lch); - omap_writew(UDC_RXN_STOP | (packets - 1), UDC_RXDMA(ep->dma_channel)); - w = omap_readw(UDC_DMA_IRQ_EN); - w |= UDC_RX_EOT_IE(ep->dma_channel); - omap_writew(w, UDC_DMA_IRQ_EN); - omap_writew(ep->bEndpointAddress & 0xf, UDC_EP_NUM); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); + UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel); + UDC_EP_NUM_REG = (ep->bEndpointAddress & 0xf); + UDC_CTRL_REG = UDC_SET_FIFO_EN; omap_start_dma(ep->lch); } @@ -650,7 +667,7 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) static void finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one) { - u16 count, w; + u16 count; if (status == 0) ep->dma_counter = (u16) (req->req.dma + req->req.actual); @@ -669,15 +686,13 @@ finish_out_dma(struct omap_ep *ep, struct omap_req *req, int status, int one) return; /* rx completion */ - w = omap_readw(UDC_DMA_IRQ_EN); - w &= ~UDC_RX_EOT_IE(ep->dma_channel); - omap_writew(w, UDC_DMA_IRQ_EN); + UDC_DMA_IRQ_EN_REG &= ~UDC_RX_EOT_IE(ep->dma_channel); done(ep, req, status); } static void dma_irq(struct omap_udc *udc, u16 irq_src) { - u16 dman_stat = omap_readw(UDC_DMAN_STAT); + u16 dman_stat = UDC_DMAN_STAT_REG; struct omap_ep *ep; struct omap_req *req; @@ -691,7 +706,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) struct omap_req, queue); finish_in_dma(ep, req, 0); } - omap_writew(UDC_TXN_DONE, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = UDC_TXN_DONE; if (!list_empty (&ep->queue)) { req = container_of(ep->queue.next, @@ -710,7 +725,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) struct omap_req, queue); finish_out_dma(ep, req, 0, dman_stat & UDC_DMA_RX_SB); } - omap_writew(UDC_RXN_EOT, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = UDC_RXN_EOT; if (!list_empty (&ep->queue)) { req = container_of(ep->queue.next, @@ -724,7 +739,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) ep->irqs++; /* omap15xx does this unasked... */ VDBG("%s, RX_CNT irq?\n", ep->ep.name); - omap_writew(UDC_RXN_CNT, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = UDC_RXN_CNT; } } @@ -747,9 +762,9 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) is_in = ep->bEndpointAddress & USB_DIR_IN; if (is_in) - reg = omap_readw(UDC_TXDMA_CFG); + reg = UDC_TXDMA_CFG_REG; else - reg = omap_readw(UDC_RXDMA_CFG); + reg = UDC_RXDMA_CFG_REG; reg |= UDC_DMA_REQ; /* "pulse" activated */ ep->dma_channel = 0; @@ -777,7 +792,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { - omap_writew(reg, UDC_TXDMA_CFG); + UDC_TXDMA_CFG_REG = reg; /* EMIFF or SDRC */ omap_set_dma_src_burst_mode(ep->lch, OMAP_DMA_DATA_BURST_4); @@ -786,7 +801,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p(UDC_DATA_DMA), + (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), 0, 0); } } else { @@ -798,12 +813,12 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) status = omap_request_dma(dma_channel, ep->ep.name, dma_error, ep, &ep->lch); if (status == 0) { - omap_writew(reg, UDC_RXDMA_CFG); + UDC_RXDMA_CFG_REG = reg; /* TIPB */ omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p(UDC_DATA_DMA), + (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), 0, 0); /* EMIFF or SDRC */ omap_set_dma_dest_burst_mode(ep->lch, @@ -819,7 +834,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) /* channel type P: hw synch (fifo) */ if (cpu_class_is_omap1() && !cpu_is_omap15xx()) - omap_set_dma_channel_mode(ep->lch, OMAP_DMA_LCH_P); + OMAP1_DMA_LCH_CTRL_REG(ep->lch) = 2; } just_restart: @@ -845,7 +860,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) (is_in ? write_fifo : read_fifo)(ep, req); deselect_ep(); if (!is_in) { - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1 + ep->double_buf; } /* IN: 6 wait states before it'll tx */ @@ -866,7 +881,7 @@ static void dma_channel_release(struct omap_ep *ep) else req = NULL; - active = omap_get_dma_active_status(ep->lch); + active = ((1 << 7) & OMAP_DMA_CCR_REG(ep->lch)) != 0; DBG("%s release %s %cxdma%d %p\n", ep->ep.name, active ? "active" : "idle", @@ -879,25 +894,23 @@ static void dma_channel_release(struct omap_ep *ep) /* wait till current packet DMA finishes, and fifo empties */ if (ep->bEndpointAddress & USB_DIR_IN) { - omap_writew((omap_readw(UDC_TXDMA_CFG) & ~mask) | UDC_DMA_REQ, - UDC_TXDMA_CFG); + UDC_TXDMA_CFG_REG = (UDC_TXDMA_CFG_REG & ~mask) | UDC_DMA_REQ; if (req) { finish_in_dma(ep, req, -ECONNRESET); /* clear FIFO; hosts probably won't empty it */ use_ep(ep, UDC_EP_SEL); - omap_writew(UDC_CLR_EP, UDC_CTRL); + UDC_CTRL_REG = UDC_CLR_EP; deselect_ep(); } - while (omap_readw(UDC_TXDMA_CFG) & mask) + while (UDC_TXDMA_CFG_REG & mask) udelay(10); } else { - omap_writew((omap_readw(UDC_RXDMA_CFG) & ~mask) | UDC_DMA_REQ, - UDC_RXDMA_CFG); + UDC_RXDMA_CFG_REG = (UDC_RXDMA_CFG_REG & ~mask) | UDC_DMA_REQ; /* dma empties the fifo */ - while (omap_readw(UDC_RXDMA_CFG) & mask) + while (UDC_RXDMA_CFG_REG & mask) udelay(10); if (req) finish_out_dma(ep, req, -ECONNRESET, 0); @@ -984,13 +997,9 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req->req.actual = 0; /* maybe kickstart non-iso i/o queues */ - if (is_iso) { - u16 w; - - w = omap_readw(UDC_IRQ_EN); - w |= UDC_SOF_IE; - omap_writew(w, UDC_IRQ_EN); - } else if (list_empty(&ep->queue) && !ep->stopped && !ep->ackwait) { + if (is_iso) + UDC_IRQ_EN_REG |= UDC_SOF_IE; + else if (list_empty(&ep->queue) && !ep->stopped && !ep->ackwait) { int is_in; if (ep->bEndpointAddress == 0) { @@ -1008,23 +1017,23 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) * requests to non-control endpoints */ if (udc->ep0_set_config) { - u16 irq_en = omap_readw(UDC_IRQ_EN); + u16 irq_en = UDC_IRQ_EN_REG; irq_en |= UDC_DS_CHG_IE | UDC_EP0_IE; if (!udc->ep0_reset_config) irq_en |= UDC_EPN_RX_IE | UDC_EPN_TX_IE; - omap_writew(irq_en, UDC_IRQ_EN); + UDC_IRQ_EN_REG = irq_en; } /* STATUS for zero length DATA stages is * always an IN ... even for IN transfers, * a weird case which seem to stall OMAP. */ - omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); - omap_writew(UDC_CLR_EP, UDC_CTRL); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR); + UDC_CTRL_REG = UDC_CLR_EP; + UDC_CTRL_REG = UDC_SET_FIFO_EN; + UDC_EP_NUM_REG = UDC_EP_DIR; /* cleanup */ udc->ep0_pending = 0; @@ -1033,11 +1042,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) /* non-empty DATA stage */ } else if (is_in) { - omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; } else { if (udc->ep0_setup) goto irq_wait; - omap_writew(UDC_EP_SEL, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_SEL; } } else { is_in = ep->bEndpointAddress & USB_DIR_IN; @@ -1053,7 +1062,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) req = NULL; deselect_ep(); if (!is_in) { - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1 + ep->double_buf; } /* IN: 6 wait states before it'll tx */ @@ -1121,9 +1130,9 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) else if (value) { if (ep->udc->ep0_set_config) { WARN("error changing config?\n"); - omap_writew(UDC_CLR_CFG, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_CLR_CFG; } - omap_writew(UDC_STALL_CMD, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_STALL_CMD; ep->udc->ep0_pending = 0; status = 0; } else /* NOP */ @@ -1150,8 +1159,8 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) channel = 0; use_ep(ep, UDC_EP_SEL); - if (omap_readw(UDC_STAT_FLG) & UDC_NON_ISO_FIFO_EMPTY) { - omap_writew(UDC_SET_HALT, UDC_CTRL); + if (UDC_STAT_FLG_REG & UDC_NON_ISO_FIFO_EMPTY) { + UDC_CTRL_REG = UDC_SET_HALT; status = 0; } else status = -EAGAIN; @@ -1161,10 +1170,10 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) dma_channel_claim(ep, channel); } else { use_ep(ep, 0); - omap_writew(ep->udc->clr_halt, UDC_CTRL); + UDC_CTRL_REG = ep->udc->clr_halt; ep->ackwait = 0; if (!(ep->bEndpointAddress & USB_DIR_IN)) { - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1 + ep->double_buf; } } @@ -1196,7 +1205,7 @@ static struct usb_ep_ops omap_ep_ops = { static int omap_get_frame(struct usb_gadget *gadget) { - u16 sof = omap_readw(UDC_SOF); + u16 sof = UDC_SOF_REG; return (sof & UDC_TS_OK) ? (sof & UDC_TS) : -EL2NSYNC; } @@ -1215,7 +1224,7 @@ static int omap_wakeup(struct usb_gadget *gadget) */ if (udc->devstat & (UDC_B_HNP_ENABLE|UDC_R_WK_OK)) { DBG("remote wakeup...\n"); - omap_writew(UDC_RMT_WKP, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_RMT_WKP; retval = 0; } @@ -1238,12 +1247,12 @@ omap_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) udc = container_of(gadget, struct omap_udc, gadget); spin_lock_irqsave(&udc->lock, flags); - syscon1 = omap_readw(UDC_SYSCON1); + syscon1 = UDC_SYSCON1_REG; if (is_selfpowered) syscon1 |= UDC_SELF_PWR; else syscon1 &= ~UDC_SELF_PWR; - omap_writew(syscon1, UDC_SYSCON1); + UDC_SYSCON1_REG = syscon1; spin_unlock_irqrestore(&udc->lock, flags); return 0; @@ -1256,36 +1265,18 @@ static int can_pullup(struct omap_udc *udc) static void pullup_enable(struct omap_udc *udc) { - u16 w; - - w = omap_readw(UDC_SYSCON1); - w |= UDC_PULLUP_EN; - omap_writew(w, UDC_SYSCON1); - if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) { - u32 l; - - l = omap_readl(OTG_CTRL); - l |= OTG_BSESSVLD; - omap_writel(l, OTG_CTRL); - } - omap_writew(UDC_DS_CHG_IE, UDC_IRQ_EN); + UDC_SYSCON1_REG |= UDC_PULLUP_EN; + if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) + OTG_CTRL_REG |= OTG_BSESSVLD; + UDC_IRQ_EN_REG = UDC_DS_CHG_IE; } static void pullup_disable(struct omap_udc *udc) { - u16 w; - - if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) { - u32 l; - - l = omap_readl(OTG_CTRL); - l &= ~OTG_BSESSVLD; - omap_writel(l, OTG_CTRL); - } - omap_writew(UDC_DS_CHG_IE, UDC_IRQ_EN); - w = omap_readw(UDC_SYSCON1); - w &= ~UDC_PULLUP_EN; - omap_writew(w, UDC_SYSCON1); + if (!gadget_is_otg(&udc->gadget) && !cpu_is_omap15xx()) + OTG_CTRL_REG &= ~OTG_BSESSVLD; + UDC_IRQ_EN_REG = UDC_DS_CHG_IE; + UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; } static struct omap_udc *udc; @@ -1313,7 +1304,6 @@ static int omap_vbus_session(struct usb_gadget *gadget, int is_active) { struct omap_udc *udc; unsigned long flags; - u32 l; udc = container_of(gadget, struct omap_udc, gadget); spin_lock_irqsave(&udc->lock, flags); @@ -1321,12 +1311,10 @@ static int omap_vbus_session(struct usb_gadget *gadget, int is_active) udc->vbus_active = (is_active != 0); if (cpu_is_omap15xx()) { /* "software" detect, ignored if !VBUS_MODE_1510 */ - l = omap_readl(FUNC_MUX_CTRL_0); if (is_active) - l |= VBUS_CTRL_1510; + FUNC_MUX_CTRL_0_REG |= VBUS_CTRL_1510; else - l &= ~VBUS_CTRL_1510; - omap_writel(l, FUNC_MUX_CTRL_0); + FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; } if (udc->dc_clk != NULL && is_active) { if (!udc->clk_requested) { @@ -1396,9 +1384,9 @@ static void nuke(struct omap_ep *ep, int status) dma_channel_release(ep); use_ep(ep, 0); - omap_writew(UDC_CLR_EP, UDC_CTRL); + UDC_CTRL_REG = UDC_CLR_EP; if (ep->bEndpointAddress && ep->bmAttributes != USB_ENDPOINT_XFER_ISOC) - omap_writew(UDC_SET_HALT, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_HALT; while (!list_empty(&ep->queue)) { req = list_entry(ep->queue.next, struct omap_req, queue); @@ -1426,8 +1414,8 @@ static void update_otg(struct omap_udc *udc) if (!gadget_is_otg(&udc->gadget)) return; - if (omap_readl(OTG_CTRL) & OTG_ID) - devstat = omap_readw(UDC_DEVSTAT); + if (OTG_CTRL_REG & OTG_ID) + devstat = UDC_DEVSTAT_REG; else devstat = 0; @@ -1438,14 +1426,9 @@ static void update_otg(struct omap_udc *udc) /* Enable HNP early, avoiding races on suspend irq path. * ASSUMES OTG state machine B_BUS_REQ input is true. */ - if (udc->gadget.b_hnp_enable) { - u32 l; - - l = omap_readl(OTG_CTRL); - l |= OTG_B_HNPEN | OTG_B_BUSREQ; - l &= ~OTG_PULLUP; - omap_writel(l, OTG_CTRL); - } + if (udc->gadget.b_hnp_enable) + OTG_CTRL_REG = (OTG_CTRL_REG | OTG_B_HNPEN | OTG_B_BUSREQ) + & ~OTG_PULLUP; } static void ep0_irq(struct omap_udc *udc, u16 irq_src) @@ -1463,7 +1446,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) nuke(ep0, 0); if (ack) { - omap_writew(ack, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = ack; irq_src = UDC_SETUP; } } @@ -1483,9 +1466,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) if (irq_src & UDC_EP0_TX) { int stat; - omap_writew(UDC_EP0_TX, UDC_IRQ_SRC); - omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM); - stat = omap_readw(UDC_STAT_FLG); + UDC_IRQ_SRC_REG = UDC_EP0_TX; + UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; + stat = UDC_STAT_FLG_REG; if (stat & UDC_ACK) { if (udc->ep0_in) { /* write next IN packet from response, @@ -1493,26 +1476,26 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) */ if (req) stat = write_fifo(ep0, req); - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_DIR; if (!req && udc->ep0_pending) { - omap_writew(UDC_EP_SEL, UDC_EP_NUM); - omap_writew(UDC_CLR_EP, UDC_CTRL); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); - omap_writew(0, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_SEL; + UDC_CTRL_REG = UDC_CLR_EP; + UDC_CTRL_REG = UDC_SET_FIFO_EN; + UDC_EP_NUM_REG = 0; udc->ep0_pending = 0; } /* else: 6 wait states before it'll tx */ } else { /* ack status stage of OUT transfer */ - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_DIR; if (req) done(ep0, req, 0); } req = NULL; } else if (stat & UDC_STALL) { - omap_writew(UDC_CLR_HALT, UDC_CTRL); - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_CTRL_REG = UDC_CLR_HALT; + UDC_EP_NUM_REG = UDC_EP_DIR; } else { - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_DIR; } } @@ -1520,9 +1503,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) if (irq_src & UDC_EP0_RX) { int stat; - omap_writew(UDC_EP0_RX, UDC_IRQ_SRC); - omap_writew(UDC_EP_SEL, UDC_EP_NUM); - stat = omap_readw(UDC_STAT_FLG); + UDC_IRQ_SRC_REG = UDC_EP0_RX; + UDC_EP_NUM_REG = UDC_EP_SEL; + stat = UDC_STAT_FLG_REG; if (stat & UDC_ACK) { if (!udc->ep0_in) { stat = 0; @@ -1530,35 +1513,34 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) * reactiviting the fifo; stall on errors. */ if (!req || (stat = read_fifo(ep0, req)) < 0) { - omap_writew(UDC_STALL_CMD, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_STALL_CMD; udc->ep0_pending = 0; stat = 0; } else if (stat == 0) - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); - omap_writew(0, UDC_EP_NUM); + UDC_CTRL_REG = UDC_SET_FIFO_EN; + UDC_EP_NUM_REG = 0; /* activate status stage */ if (stat == 1) { done(ep0, req, 0); /* that may have STALLed ep0... */ - omap_writew(UDC_EP_SEL | UDC_EP_DIR, - UDC_EP_NUM); - omap_writew(UDC_CLR_EP, UDC_CTRL); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; + UDC_CTRL_REG = UDC_CLR_EP; + UDC_CTRL_REG = UDC_SET_FIFO_EN; + UDC_EP_NUM_REG = UDC_EP_DIR; udc->ep0_pending = 0; } } else { /* ack status stage of IN transfer */ - omap_writew(0, UDC_EP_NUM); + UDC_EP_NUM_REG = 0; if (req) done(ep0, req, 0); } } else if (stat & UDC_STALL) { - omap_writew(UDC_CLR_HALT, UDC_CTRL); - omap_writew(0, UDC_EP_NUM); + UDC_CTRL_REG = UDC_CLR_HALT; + UDC_EP_NUM_REG = 0; } else { - omap_writew(0, UDC_EP_NUM); + UDC_EP_NUM_REG = 0; } } @@ -1573,14 +1555,14 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) /* read the (latest) SETUP message */ do { - omap_writew(UDC_SETUP_SEL, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_SETUP_SEL; /* two bytes at a time */ - u.word[0] = omap_readw(UDC_DATA); - u.word[1] = omap_readw(UDC_DATA); - u.word[2] = omap_readw(UDC_DATA); - u.word[3] = omap_readw(UDC_DATA); - omap_writew(0, UDC_EP_NUM); - } while (omap_readw(UDC_IRQ_SRC) & UDC_SETUP); + u.word[0] = UDC_DATA_REG; + u.word[1] = UDC_DATA_REG; + u.word[2] = UDC_DATA_REG; + u.word[3] = UDC_DATA_REG; + UDC_EP_NUM_REG = 0; + } while (UDC_IRQ_SRC_REG & UDC_SETUP); #define w_value le16_to_cpu(u.r.wValue) #define w_index le16_to_cpu(u.r.wIndex) @@ -1611,9 +1593,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) * later if it fails the request. */ if (udc->ep0_reset_config) - omap_writew(UDC_CLR_CFG, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_CLR_CFG; else - omap_writew(UDC_DEV_CFG, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_DEV_CFG; update_otg(udc); goto delegate; case USB_REQ_CLEAR_FEATURE: @@ -1631,10 +1613,10 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) || !ep->desc) goto do_stall; use_ep(ep, 0); - omap_writew(udc->clr_halt, UDC_CTRL); + UDC_CTRL_REG = udc->clr_halt; ep->ackwait = 0; if (!(ep->bEndpointAddress & USB_DIR_IN)) { - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1 + ep->double_buf; } /* NOTE: assumes the host behaves sanely, @@ -1667,15 +1649,15 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) } use_ep(ep, 0); /* can't halt if fifo isn't empty... */ - omap_writew(UDC_CLR_EP, UDC_CTRL); - omap_writew(UDC_SET_HALT, UDC_CTRL); + UDC_CTRL_REG = UDC_CLR_EP; + UDC_CTRL_REG = UDC_SET_HALT; VDBG("%s halted by host\n", ep->name); ep0out_status_stage: status = 0; - omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM); - omap_writew(UDC_CLR_EP, UDC_CTRL); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; + UDC_CTRL_REG = UDC_CLR_EP; + UDC_CTRL_REG = UDC_SET_FIFO_EN; + UDC_EP_NUM_REG = UDC_EP_DIR; udc->ep0_pending = 0; break; case USB_REQ_GET_STATUS: @@ -1712,10 +1694,10 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) zero_status: /* return two zero bytes */ - omap_writew(UDC_EP_SEL|UDC_EP_DIR, UDC_EP_NUM); - omap_writew(0, UDC_DATA); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); - omap_writew(UDC_EP_DIR, UDC_EP_NUM); + UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; + UDC_DATA_REG = 0; + UDC_CTRL_REG = UDC_SET_FIFO_EN; + UDC_EP_NUM_REG = UDC_EP_DIR; status = 0; VDBG("GET_STATUS, interface %d\n", w_index); /* next, status stage */ @@ -1724,8 +1706,8 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) delegate: /* activate the ep0out fifo right away */ if (!udc->ep0_in && w_length) { - omap_writew(0, UDC_EP_NUM); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_EP_NUM_REG = 0; + UDC_CTRL_REG = UDC_SET_FIFO_EN; } /* gadget drivers see class/vendor specific requests, @@ -1766,9 +1748,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) if (udc->ep0_reset_config) WARN("error resetting config?\n"); else - omap_writew(UDC_CLR_CFG, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_CLR_CFG; } - omap_writew(UDC_STALL_CMD, UDC_SYSCON2); + UDC_SYSCON2_REG = UDC_STALL_CMD; udc->ep0_pending = 0; } } @@ -1782,7 +1764,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) { u16 devstat, change; - devstat = omap_readw(UDC_DEVSTAT); + devstat = UDC_DEVSTAT_REG; change = devstat ^ udc->devstat; udc->devstat = devstat; @@ -1822,8 +1804,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) INFO("USB reset done, gadget %s\n", udc->driver->driver.name); /* ep0 traffic is legal from now on */ - omap_writew(UDC_DS_CHG_IE | UDC_EP0_IE, - UDC_IRQ_EN); + UDC_IRQ_EN_REG = UDC_DS_CHG_IE | UDC_EP0_IE; } change &= ~UDC_USB_RESET; } @@ -1867,7 +1848,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) VDBG("devstat %03x, ignore change %03x\n", devstat, change); - omap_writew(UDC_DS_CHG, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = UDC_DS_CHG; } static irqreturn_t omap_udc_irq(int irq, void *_udc) @@ -1878,7 +1859,7 @@ static irqreturn_t omap_udc_irq(int irq, void *_udc) unsigned long flags; spin_lock_irqsave(&udc->lock, flags); - irq_src = omap_readw(UDC_IRQ_SRC); + irq_src = UDC_IRQ_SRC_REG; /* Device state change (usb ch9 stuff) */ if (irq_src & UDC_DS_CHG) { @@ -1901,7 +1882,7 @@ static irqreturn_t omap_udc_irq(int irq, void *_udc) irq_src &= ~(UDC_TXN_DONE|UDC_RXN_CNT|UDC_RXN_EOT); } - irq_src &= ~(UDC_IRQ_SOF | UDC_EPN_TX|UDC_EPN_RX); + irq_src &= ~(UDC_SOF|UDC_EPN_TX|UDC_EPN_RX); if (irq_src) DBG("udc_irq, unhandled %03x\n", irq_src); spin_unlock_irqrestore(&udc->lock, flags); @@ -1922,7 +1903,7 @@ static void pio_out_timer(unsigned long _ep) spin_lock_irqsave(&ep->udc->lock, flags); if (!list_empty(&ep->queue) && ep->ackwait) { use_ep(ep, UDC_EP_SEL); - stat_flg = omap_readw(UDC_STAT_FLG); + stat_flg = UDC_STAT_FLG_REG; if ((stat_flg & UDC_ACK) && (!(stat_flg & UDC_FIFO_EN) || (ep->double_buf && HALF_FULL(stat_flg)))) { @@ -1932,8 +1913,8 @@ static void pio_out_timer(unsigned long _ep) req = container_of(ep->queue.next, struct omap_req, queue); (void) read_fifo(ep, req); - omap_writew(ep->bEndpointAddress, UDC_EP_NUM); - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_EP_NUM_REG = ep->bEndpointAddress; + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1 + ep->double_buf; } else deselect_ep(); @@ -1953,20 +1934,20 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) unsigned long flags; spin_lock_irqsave(&udc->lock, flags); - epn_stat = omap_readw(UDC_EPN_STAT); - irq_src = omap_readw(UDC_IRQ_SRC); + epn_stat = UDC_EPN_STAT_REG; + irq_src = UDC_IRQ_SRC_REG; /* handle OUT first, to avoid some wasteful NAKs */ if (irq_src & UDC_EPN_RX) { epnum = (epn_stat >> 8) & 0x0f; - omap_writew(UDC_EPN_RX, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = UDC_EPN_RX; status = IRQ_HANDLED; ep = &udc->ep[epnum]; ep->irqs++; - omap_writew(epnum | UDC_EP_SEL, UDC_EP_NUM); + UDC_EP_NUM_REG = epnum | UDC_EP_SEL; ep->fnf = 0; - if (omap_readw(UDC_STAT_FLG) & UDC_ACK) { + if ((UDC_STAT_FLG_REG & UDC_ACK)) { ep->ackwait--; if (!list_empty(&ep->queue)) { int stat; @@ -1978,15 +1959,15 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) } } /* min 6 clock delay before clearing EP_SEL ... */ - epn_stat = omap_readw(UDC_EPN_STAT); - epn_stat = omap_readw(UDC_EPN_STAT); - omap_writew(epnum, UDC_EP_NUM); + epn_stat = UDC_EPN_STAT_REG; + epn_stat = UDC_EPN_STAT_REG; + UDC_EP_NUM_REG = epnum; /* enabling fifo _after_ clearing ACK, contrary to docs, * reduces lossage; timer still needed though (sigh). */ if (ep->fnf) { - omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_FIFO_EN; ep->ackwait = 1 + ep->double_buf; } mod_timer(&ep->timer, PIO_OUT_TIMEOUT); @@ -1995,13 +1976,13 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) /* then IN transfers */ else if (irq_src & UDC_EPN_TX) { epnum = epn_stat & 0x0f; - omap_writew(UDC_EPN_TX, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = UDC_EPN_TX; status = IRQ_HANDLED; ep = &udc->ep[16 + epnum]; ep->irqs++; - omap_writew(epnum | UDC_EP_DIR | UDC_EP_SEL, UDC_EP_NUM); - if (omap_readw(UDC_STAT_FLG) & UDC_ACK) { + UDC_EP_NUM_REG = epnum | UDC_EP_DIR | UDC_EP_SEL; + if ((UDC_STAT_FLG_REG & UDC_ACK)) { ep->ackwait = 0; if (!list_empty(&ep->queue)) { req = container_of(ep->queue.next, @@ -2010,9 +1991,9 @@ static irqreturn_t omap_udc_pio_irq(int irq, void *_dev) } } /* min 6 clock delay before clearing EP_SEL ... */ - epn_stat = omap_readw(UDC_EPN_STAT); - epn_stat = omap_readw(UDC_EPN_STAT); - omap_writew(epnum | UDC_EP_DIR, UDC_EP_NUM); + epn_stat = UDC_EPN_STAT_REG; + epn_stat = UDC_EPN_STAT_REG; + UDC_EP_NUM_REG = epnum | UDC_EP_DIR; /* then 6 clocks before it'd tx */ } @@ -2040,7 +2021,7 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) req = list_entry(ep->queue.next, struct omap_req, queue); use_ep(ep, UDC_EP_SEL); - stat = omap_readw(UDC_STAT_FLG); + stat = UDC_STAT_FLG_REG; /* NOTE: like the other controller drivers, this isn't * currently reporting lost or damaged frames. @@ -2072,14 +2053,9 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) if (!list_empty(&ep->queue)) pending = 1; } - if (!pending) { - u16 w; - - w = omap_readw(UDC_IRQ_EN); - w &= ~UDC_SOF_IE; - omap_writew(w, UDC_IRQ_EN); - } - omap_writew(UDC_IRQ_SOF, UDC_IRQ_SRC); + if (!pending) + UDC_IRQ_EN_REG &= ~UDC_SOF_IE; + UDC_IRQ_SRC_REG = UDC_SOF; spin_unlock_irqrestore(&udc->lock, flags); return IRQ_HANDLED; @@ -2128,7 +2104,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) continue; use_ep(ep, 0); - omap_writew(UDC_SET_HALT, UDC_CTRL); + UDC_CTRL_REG = UDC_SET_HALT; } udc->ep0_pending = 0; udc->ep[0].irqs = 0; @@ -2152,7 +2128,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) } DBG("bound to driver %s\n", driver->driver.name); - omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); + UDC_IRQ_SRC_REG = UDC_IRQ_SRC_MASK; /* connect to bus through transceiver */ if (udc->transceiver) { @@ -2249,7 +2225,7 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) else buf[0] = 0; - stat_flg = omap_readw(UDC_STAT_FLG); + stat_flg = UDC_STAT_FLG_REG; seq_printf(s, "\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", ep->name, buf, @@ -2316,11 +2292,11 @@ static int proc_otg_show(struct seq_file *s) trans = CONTROL_DEVCONF_REG; } else { ctrl_name = "tranceiver_ctrl"; - trans = omap_readw(USB_TRANSCEIVER_CTRL); + trans = USB_TRANSCEIVER_CTRL_REG; } seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", tmp >> 4, tmp & 0xf, ctrl_name, trans); - tmp = omap_readw(OTG_SYSCON_1); + tmp = OTG_SYSCON_1_REG; seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," FOURBITS "\n", tmp, trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R), @@ -2332,7 +2308,7 @@ static int proc_otg_show(struct seq_file *s) (tmp & HST_IDLE_EN) ? " !host" : "", (tmp & DEV_IDLE_EN) ? " !dev" : "", (tmp & OTG_RESET_DONE) ? " reset_done" : " reset_active"); - tmp = omap_readl(OTG_SYSCON_2); + tmp = OTG_SYSCON_2_REG; seq_printf(s, "otg_syscon2 %08x%s" EIGHTBITS " b_ase_brst=%d hmc=%d\n", tmp, (tmp & OTG_EN) ? " otg_en" : "", @@ -2347,7 +2323,7 @@ static int proc_otg_show(struct seq_file *s) (tmp & HMC_TLLATTACH) ? " tllattach" : "", B_ASE_BRST(tmp), OTG_HMC(tmp)); - tmp = omap_readl(OTG_CTRL); + tmp = OTG_CTRL_REG; seq_printf(s, "otg_ctrl %06x" EIGHTBITS EIGHTBITS "%s\n", tmp, (tmp & OTG_ASESSVLD) ? " asess" : "", (tmp & OTG_BSESSEND) ? " bsess_end" : "", @@ -2367,13 +2343,13 @@ static int proc_otg_show(struct seq_file *s) (tmp & OTG_PU_VBUS) ? " pu_vb" : "", (tmp & OTG_PU_ID) ? " pu_id" : "" ); - tmp = omap_readw(OTG_IRQ_EN); + tmp = OTG_IRQ_EN_REG; seq_printf(s, "otg_irq_en %04x" "\n", tmp); - tmp = omap_readw(OTG_IRQ_SRC); + tmp = OTG_IRQ_SRC_REG; seq_printf(s, "otg_irq_src %04x" "\n", tmp); - tmp = omap_readw(OTG_OUTCTRL); + tmp = OTG_OUTCTRL_REG; seq_printf(s, "otg_outctrl %04x" "\n", tmp); - tmp = omap_readw(OTG_TEST); + tmp = OTG_TEST_REG; seq_printf(s, "otg_test %04x" "\n", tmp); return 0; } @@ -2394,7 +2370,7 @@ static int proc_udc_show(struct seq_file *s, void *_) driver_desc, use_dma ? " (dma)" : ""); - tmp = omap_readw(UDC_REV) & 0xff; + tmp = UDC_REV_REG & 0xff; seq_printf(s, "UDC rev %d.%d, fifo mode %d, gadget %s\n" "hmc %d, transceiver %s\n", @@ -2408,16 +2384,16 @@ static int proc_udc_show(struct seq_file *s, void *_) ? "external" : "(none)")); if (cpu_class_is_omap1()) { seq_printf(s, "ULPD control %04x req %04x status %04x\n", - omap_readw(ULPD_CLOCK_CTRL), - omap_readw(ULPD_SOFT_REQ), - omap_readw(ULPD_STATUS_REQ)); + __REG16(ULPD_CLOCK_CTRL), + __REG16(ULPD_SOFT_REQ), + __REG16(ULPD_STATUS_REQ)); } /* OTG controller registers */ if (!cpu_is_omap15xx()) proc_otg_show(s); - tmp = omap_readw(UDC_SYSCON1); + tmp = UDC_SYSCON1_REG; seq_printf(s, "\nsyscon1 %04x" EIGHTBITS "\n", tmp, (tmp & UDC_CFG_LOCK) ? " cfg_lock" : "", (tmp & UDC_DATA_ENDIAN) ? " data_endian" : "", @@ -2436,7 +2412,7 @@ static int proc_udc_show(struct seq_file *s, void *_) return 0; } - tmp = omap_readw(UDC_DEVSTAT); + tmp = UDC_DEVSTAT_REG; seq_printf(s, "devstat %04x" EIGHTBITS "%s%s\n", tmp, (tmp & UDC_B_HNP_ENABLE) ? " b_hnp" : "", (tmp & UDC_A_HNP_SUPPORT) ? " a_hnp" : "", @@ -2448,20 +2424,20 @@ static int proc_udc_show(struct seq_file *s, void *_) (tmp & UDC_ADD) ? " ADD" : "", (tmp & UDC_DEF) ? " DEF" : "", (tmp & UDC_ATT) ? " ATT" : ""); - seq_printf(s, "sof %04x\n", omap_readw(UDC_SOF)); - tmp = omap_readw(UDC_IRQ_EN); + seq_printf(s, "sof %04x\n", UDC_SOF_REG); + tmp = UDC_IRQ_EN_REG; seq_printf(s, "irq_en %04x" FOURBITS "%s\n", tmp, (tmp & UDC_SOF_IE) ? " sof" : "", (tmp & UDC_EPN_RX_IE) ? " epn_rx" : "", (tmp & UDC_EPN_TX_IE) ? " epn_tx" : "", (tmp & UDC_DS_CHG_IE) ? " ds_chg" : "", (tmp & UDC_EP0_IE) ? " ep0" : ""); - tmp = omap_readw(UDC_IRQ_SRC); + tmp = UDC_IRQ_SRC_REG; seq_printf(s, "irq_src %04x" EIGHTBITS "%s%s\n", tmp, (tmp & UDC_TXN_DONE) ? " txn_done" : "", (tmp & UDC_RXN_CNT) ? " rxn_cnt" : "", (tmp & UDC_RXN_EOT) ? " rxn_eot" : "", - (tmp & UDC_IRQ_SOF) ? " sof" : "", + (tmp & UDC_SOF) ? " sof" : "", (tmp & UDC_EPN_RX) ? " epn_rx" : "", (tmp & UDC_EPN_TX) ? " epn_tx" : "", (tmp & UDC_DS_CHG) ? " ds_chg" : "", @@ -2471,7 +2447,7 @@ static int proc_udc_show(struct seq_file *s, void *_) if (use_dma) { unsigned i; - tmp = omap_readw(UDC_DMA_IRQ_EN); + tmp = UDC_DMA_IRQ_EN_REG; seq_printf(s, "dma_irq_en %04x%s" EIGHTBITS "\n", tmp, (tmp & UDC_TX_DONE_IE(3)) ? " tx2_done" : "", (tmp & UDC_RX_CNT_IE(3)) ? " rx2_cnt" : "", @@ -2485,29 +2461,29 @@ static int proc_udc_show(struct seq_file *s, void *_) (tmp & UDC_RX_CNT_IE(1)) ? " rx0_cnt" : "", (tmp & UDC_RX_EOT_IE(1)) ? " rx0_eot" : ""); - tmp = omap_readw(UDC_RXDMA_CFG); + tmp = UDC_RXDMA_CFG_REG; seq_printf(s, "rxdma_cfg %04x\n", tmp); if (tmp) { for (i = 0; i < 3; i++) { if ((tmp & (0x0f << (i * 4))) == 0) continue; seq_printf(s, "rxdma[%d] %04x\n", i, - omap_readw(UDC_RXDMA(i + 1))); + UDC_RXDMA_REG(i + 1)); } } - tmp = omap_readw(UDC_TXDMA_CFG); + tmp = UDC_TXDMA_CFG_REG; seq_printf(s, "txdma_cfg %04x\n", tmp); if (tmp) { for (i = 0; i < 3; i++) { if (!(tmp & (0x0f << (i * 4)))) continue; seq_printf(s, "txdma[%d] %04x\n", i, - omap_readw(UDC_TXDMA(i + 1))); + UDC_TXDMA_REG(i + 1)); } } } - tmp = omap_readw(UDC_DEVSTAT); + tmp = UDC_DEVSTAT_REG; if (tmp & UDC_ATT) { proc_ep_show(s, &udc->ep[0]); if (tmp & UDC_ADD) { @@ -2559,7 +2535,7 @@ static inline void remove_proc_file(void) {} * buffer space among the endpoints we'll be operating. * * NOTE: as of OMAP 1710 ES2.0, writing a new endpoint config when - * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that + * UDC_SYSCON_1_REG.CFG_LOCK is set can now work. We won't use that * capability yet though. */ static unsigned __init @@ -2621,9 +2597,9 @@ omap_ep_setup(char *name, u8 addr, u8 type, name, addr, epn_rxtx, maxp, dbuf ? "x2" : "", buf); if (addr & USB_DIR_IN) - omap_writew(epn_rxtx, UDC_EP_TX(addr & 0xf)); + UDC_EP_TX_REG(addr & 0xf) = epn_rxtx; else - omap_writew(epn_rxtx, UDC_EP_RX(addr)); + UDC_EP_RX_REG(addr) = epn_rxtx; /* next endpoint's buffer starts after this one's */ buf += maxp; @@ -2662,15 +2638,15 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) unsigned tmp, buf; /* abolish any previous hardware state */ - omap_writew(0, UDC_SYSCON1); - omap_writew(0, UDC_IRQ_EN); - omap_writew(UDC_IRQ_SRC_MASK, UDC_IRQ_SRC); - omap_writew(0, UDC_DMA_IRQ_EN); - omap_writew(0, UDC_RXDMA_CFG); - omap_writew(0, UDC_TXDMA_CFG); + UDC_SYSCON1_REG = 0; + UDC_IRQ_EN_REG = 0; + UDC_IRQ_SRC_REG = UDC_IRQ_SRC_MASK; + UDC_DMA_IRQ_EN_REG = 0; + UDC_RXDMA_CFG_REG = 0; + UDC_TXDMA_CFG_REG = 0; /* UDC_PULLUP_EN gates the chip clock */ - // OTG_SYSCON_1 |= DEV_IDLE_EN; + // OTG_SYSCON_1_REG |= DEV_IDLE_EN; udc = kzalloc(sizeof(*udc), GFP_KERNEL); if (!udc) @@ -2701,8 +2677,8 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) /* initially disable all non-ep0 endpoints */ for (tmp = 1; tmp < 15; tmp++) { - omap_writew(0, UDC_EP_RX(tmp)); - omap_writew(0, UDC_EP_TX(tmp)); + UDC_EP_RX_REG(tmp) = 0; + UDC_EP_TX_REG(tmp) = 0; } #define OMAP_BULK_EP(name,addr) \ @@ -2787,7 +2763,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) ERR("unsupported fifo_mode #%d\n", fifo_mode); return -ENODEV; } - omap_writew(UDC_CFG_LOCK|UDC_SELF_PWR, UDC_SYSCON1); + UDC_SYSCON1_REG = UDC_CFG_LOCK|UDC_SELF_PWR; INFO("fifo mode %d, %d bytes not used\n", fifo_mode, 2048 - buf); return 0; } @@ -2831,7 +2807,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) } INFO("OMAP UDC rev %d.%d%s\n", - omap_readw(UDC_REV) >> 4, omap_readw(UDC_REV) & 0xf, + UDC_REV_REG >> 4, UDC_REV_REG & 0xf, config->otg ? ", Mini-AB" : ""); /* use the mode given to us by board init code */ @@ -2846,12 +2822,12 @@ static int __init omap_udc_probe(struct platform_device *pdev) * know when to turn PULLUP_EN on/off; and that * means we always "need" the 48MHz clock. */ - u32 tmp = omap_readl(FUNC_MUX_CTRL_0); - tmp &= ~VBUS_CTRL_1510; - omap_writel(tmp, FUNC_MUX_CTRL_0); + u32 tmp = FUNC_MUX_CTRL_0_REG; + + FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; tmp |= VBUS_MODE_1510; tmp &= ~VBUS_CTRL_1510; - omap_writel(tmp, FUNC_MUX_CTRL_0); + FUNC_MUX_CTRL_0_REG = tmp; } } else { /* The transceiver may package some GPIO logic or handle @@ -2931,7 +2907,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) #endif /* starting with omap1710 es2.0, clear toggle is a separate bit */ - if (omap_readw(UDC_REV) >= 0x61) + if (UDC_REV_REG >= 0x61) udc->clr_halt = UDC_RESET_EP | UDC_CLRDATA_TOGGLE; else udc->clr_halt = UDC_RESET_EP; @@ -3029,7 +3005,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev) put_device(udc->transceiver->dev); udc->transceiver = NULL; } - omap_writew(0, UDC_SYSCON1); + UDC_SYSCON1_REG = 0; remove_proc_file(); @@ -3060,7 +3036,7 @@ static int __exit omap_udc_remove(struct platform_device *pdev) * * REVISIT we should probably reject suspend requests when there's a host * session active, rather than disconnecting, at least on boards that can - * report VBUS irqs (UDC_DEVSTAT.UDC_ATT). And in any case, we need to + * report VBUS irqs (UDC_DEVSTAT_REG.UDC_ATT). And in any case, we need to * make host resumes and VBUS detection trigger OMAP wakeup events; that * may involve talking to an external transceiver (e.g. isp1301). */ @@ -3069,7 +3045,7 @@ static int omap_udc_suspend(struct platform_device *dev, pm_message_t message) { u32 devstat; - devstat = omap_readw(UDC_DEVSTAT); + devstat = UDC_DEVSTAT_REG; /* we're requesting 48 MHz clock if the pullup is enabled * (== we're attached to the host) and we're not suspended, diff --git a/trunk/drivers/usb/gadget/omap_udc.h b/trunk/drivers/usb/gadget/omap_udc.h index 8522bbb12278..c6b9cbc7230a 100644 --- a/trunk/drivers/usb/gadget/omap_udc.h +++ b/trunk/drivers/usb/gadget/omap_udc.h @@ -8,22 +8,23 @@ /* * USB device/endpoint management registers */ +#define UDC_REG(offset) __REG16(UDC_BASE + (offset)) -#define UDC_REV (UDC_BASE + 0x0) /* Revision */ -#define UDC_EP_NUM (UDC_BASE + 0x4) /* Which endpoint */ +#define UDC_REV_REG UDC_REG(0x0) /* Revision */ +#define UDC_EP_NUM_REG UDC_REG(0x4) /* Which endpoint */ # define UDC_SETUP_SEL (1 << 6) # define UDC_EP_SEL (1 << 5) # define UDC_EP_DIR (1 << 4) /* low 4 bits for endpoint number */ -#define UDC_DATA (UDC_BASE + 0x08) /* Endpoint FIFO */ -#define UDC_CTRL (UDC_BASE + 0x0C) /* Endpoint control */ +#define UDC_DATA_REG UDC_REG(0x08) /* Endpoint FIFO */ +#define UDC_CTRL_REG UDC_REG(0x0C) /* Endpoint control */ # define UDC_CLR_HALT (1 << 7) # define UDC_SET_HALT (1 << 6) # define UDC_CLRDATA_TOGGLE (1 << 3) # define UDC_SET_FIFO_EN (1 << 2) # define UDC_CLR_EP (1 << 1) # define UDC_RESET_EP (1 << 0) -#define UDC_STAT_FLG (UDC_BASE + 0x10) /* Endpoint status */ +#define UDC_STAT_FLG_REG UDC_REG(0x10) /* Endpoint status */ # define UDC_NO_RXPACKET (1 << 15) # define UDC_MISS_IN (1 << 14) # define UDC_DATA_FLUSH (1 << 13) @@ -37,8 +38,8 @@ # define UDC_FIFO_EN (1 << 2) # define UDC_NON_ISO_FIFO_EMPTY (1 << 1) # define UDC_NON_ISO_FIFO_FULL (1 << 0) -#define UDC_RXFSTAT (UDC_BASE + 0x14) /* OUT bytecount */ -#define UDC_SYSCON1 (UDC_BASE + 0x18) /* System config 1 */ +#define UDC_RXFSTAT_REG UDC_REG(0x14) /* OUT bytecount */ +#define UDC_SYSCON1_REG UDC_REG(0x18) /* System config 1 */ # define UDC_CFG_LOCK (1 << 8) # define UDC_DATA_ENDIAN (1 << 7) # define UDC_DMA_ENDIAN (1 << 6) @@ -47,12 +48,12 @@ # define UDC_SELF_PWR (1 << 2) # define UDC_SOFF_DIS (1 << 1) # define UDC_PULLUP_EN (1 << 0) -#define UDC_SYSCON2 (UDC_BASE + 0x1C) /* System config 2 */ +#define UDC_SYSCON2_REG UDC_REG(0x1C) /* System config 2 */ # define UDC_RMT_WKP (1 << 6) # define UDC_STALL_CMD (1 << 5) # define UDC_DEV_CFG (1 << 3) # define UDC_CLR_CFG (1 << 2) -#define UDC_DEVSTAT (UDC_BASE + 0x20) /* Device status */ +#define UDC_DEVSTAT_REG UDC_REG(0x20) /* Device status */ # define UDC_B_HNP_ENABLE (1 << 9) # define UDC_A_HNP_SUPPORT (1 << 8) # define UDC_A_ALT_HNP_SUPPORT (1 << 7) @@ -63,26 +64,26 @@ # define UDC_ADD (1 << 2) # define UDC_DEF (1 << 1) # define UDC_ATT (1 << 0) -#define UDC_SOF (UDC_BASE + 0x24) /* Start of frame */ +#define UDC_SOF_REG UDC_REG(0x24) /* Start of frame */ # define UDC_FT_LOCK (1 << 12) # define UDC_TS_OK (1 << 11) # define UDC_TS 0x03ff -#define UDC_IRQ_EN (UDC_BASE + 0x28) /* Interrupt enable */ +#define UDC_IRQ_EN_REG UDC_REG(0x28) /* Interrupt enable */ # define UDC_SOF_IE (1 << 7) # define UDC_EPN_RX_IE (1 << 5) # define UDC_EPN_TX_IE (1 << 4) # define UDC_DS_CHG_IE (1 << 3) # define UDC_EP0_IE (1 << 0) -#define UDC_DMA_IRQ_EN (UDC_BASE + 0x2C) /* DMA irq enable */ +#define UDC_DMA_IRQ_EN_REG UDC_REG(0x2C) /* DMA irq enable */ /* rx/tx dma channels numbered 1-3 not 0-2 */ # define UDC_TX_DONE_IE(n) (1 << (4 * (n) - 2)) # define UDC_RX_CNT_IE(n) (1 << (4 * (n) - 3)) # define UDC_RX_EOT_IE(n) (1 << (4 * (n) - 4)) -#define UDC_IRQ_SRC (UDC_BASE + 0x30) /* Interrupt source */ +#define UDC_IRQ_SRC_REG UDC_REG(0x30) /* Interrupt source */ # define UDC_TXN_DONE (1 << 10) # define UDC_RXN_CNT (1 << 9) # define UDC_RXN_EOT (1 << 8) -# define UDC_IRQ_SOF (1 << 7) +# define UDC_SOF (1 << 7) # define UDC_EPN_RX (1 << 5) # define UDC_EPN_TX (1 << 4) # define UDC_DS_CHG (1 << 3) @@ -90,41 +91,41 @@ # define UDC_EP0_RX (1 << 1) # define UDC_EP0_TX (1 << 0) # define UDC_IRQ_SRC_MASK 0x7bf -#define UDC_EPN_STAT (UDC_BASE + 0x34) /* EP irq status */ -#define UDC_DMAN_STAT (UDC_BASE + 0x38) /* DMA irq status */ +#define UDC_EPN_STAT_REG UDC_REG(0x34) /* EP irq status */ +#define UDC_DMAN_STAT_REG UDC_REG(0x38) /* DMA irq status */ # define UDC_DMA_RX_SB (1 << 12) # define UDC_DMA_RX_SRC(x) (((x)>>8) & 0xf) # define UDC_DMA_TX_SRC(x) (((x)>>0) & 0xf) /* DMA configuration registers: up to three channels in each direction. */ -#define UDC_RXDMA_CFG (UDC_BASE + 0x40) /* 3 eps for RX DMA */ +#define UDC_RXDMA_CFG_REG UDC_REG(0x40) /* 3 eps for RX DMA */ # define UDC_DMA_REQ (1 << 12) -#define UDC_TXDMA_CFG (UDC_BASE + 0x44) /* 3 eps for TX DMA */ -#define UDC_DATA_DMA (UDC_BASE + 0x48) /* rx/tx fifo addr */ +#define UDC_TXDMA_CFG_REG UDC_REG(0x44) /* 3 eps for TX DMA */ +#define UDC_DATA_DMA_REG UDC_REG(0x48) /* rx/tx fifo addr */ /* rx/tx dma control, numbering channels 1-3 not 0-2 */ -#define UDC_TXDMA(chan) (UDC_BASE + 0x50 - 4 + 4 * (chan)) +#define UDC_TXDMA_REG(chan) UDC_REG(0x50 - 4 + 4 * (chan)) # define UDC_TXN_EOT (1 << 15) /* bytes vs packets */ # define UDC_TXN_START (1 << 14) /* start transfer */ # define UDC_TXN_TSC 0x03ff /* units in xfer */ -#define UDC_RXDMA(chan) (UDC_BASE + 0x60 - 4 + 4 * (chan)) +#define UDC_RXDMA_REG(chan) UDC_REG(0x60 - 4 + 4 * (chan)) # define UDC_RXN_STOP (1 << 15) /* enable EOT irq */ # define UDC_RXN_TC 0x00ff /* packets in xfer */ /* * Endpoint configuration registers (used before CFG_LOCK is set) - * UDC_EP_TX(0) is unused + * UDC_EP_TX_REG(0) is unused */ -#define UDC_EP_RX(endpoint) (UDC_BASE + 0x80 + (endpoint)*4) +#define UDC_EP_RX_REG(endpoint) UDC_REG(0x80 + (endpoint)*4) # define UDC_EPN_RX_VALID (1 << 15) # define UDC_EPN_RX_DB (1 << 14) /* buffer size in bits 13, 12 */ # define UDC_EPN_RX_ISO (1 << 11) /* buffer pointer in low 11 bits */ -#define UDC_EP_TX(endpoint) (UDC_BASE + 0xc0 + (endpoint)*4) - /* same bitfields as in RX */ +#define UDC_EP_TX_REG(endpoint) UDC_REG(0xc0 + (endpoint)*4) + /* same bitfields as in RX_REG */ /*-------------------------------------------------------------------------*/ @@ -194,14 +195,14 @@ struct omap_udc { /*-------------------------------------------------------------------------*/ -/* MOD_CONF_CTRL_0 */ -#define VBUS_W2FC_1510 (1 << 17) /* 0 gpio0, 1 dvdd2 pin */ +#define MOD_CONF_CTRL_0_REG __REG32(MOD_CONF_CTRL_0) +#define VBUS_W2FC_1510 (1 << 17) /* 0 gpio0, 1 dvdd2 pin */ -/* FUNC_MUX_CTRL_0 */ +#define FUNC_MUX_CTRL_0_REG __REG32(FUNC_MUX_CTRL_0) #define VBUS_CTRL_1510 (1 << 19) /* 1 connected (software) */ #define VBUS_MODE_1510 (1 << 18) /* 0 hardware, 1 software */ -#define HMC_1510 ((omap_readl(MOD_CONF_CTRL_0) >> 1) & 0x3f) -#define HMC_1610 (omap_readl(OTG_SYSCON_2) & 0x3f) +#define HMC_1510 ((MOD_CONF_CTRL_0_REG >> 1) & 0x3f) +#define HMC_1610 (OTG_SYSCON_2_REG & 0x3f) #define HMC (cpu_is_omap15xx() ? HMC_1510 : HMC_1610) diff --git a/trunk/drivers/usb/host/ohci-omap.c b/trunk/drivers/usb/host/ohci-omap.c index 2b7c04079d56..6859fb5f1d6f 100644 --- a/trunk/drivers/usb/host/ohci-omap.c +++ b/trunk/drivers/usb/host/ohci-omap.c @@ -169,16 +169,13 @@ static void start_hnp(struct ohci_hcd *ohci) { const unsigned port = ohci_to_hcd(ohci)->self.otg_port - 1; unsigned long flags; - u32 l; otg_start_hnp(ohci->transceiver); local_irq_save(flags); ohci->transceiver->state = OTG_STATE_A_SUSPEND; writel (RH_PS_PSS, &ohci->regs->roothub.portstatus [port]); - l = omap_readl(OTG_CTRL); - l &= ~OTG_A_BUSREQ; - omap_writel(l, OTG_CTRL); + OTG_CTRL_REG &= ~OTG_A_BUSREQ; local_irq_restore(flags); } diff --git a/trunk/drivers/video/pxafb.c b/trunk/drivers/video/pxafb.c index fafe7db20d6d..7dcda187d9ba 100644 --- a/trunk/drivers/video/pxafb.c +++ b/trunk/drivers/video/pxafb.c @@ -1246,7 +1246,7 @@ static int pxafb_resume(struct platform_device *dev) * cache. Once this area is remapped, all virtual memory * access to the video memory should occur at the new region. */ -static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi) +static int __init pxafb_map_video_memory(struct pxafb_info *fbi) { /* * We reserve one page for the palette, plus the size @@ -1348,7 +1348,7 @@ static void pxafb_decode_mach_info(struct pxafb_info *fbi, pxafb_decode_mode_info(fbi, inf->modes, inf->num_modes); } -static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) +static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) { struct pxafb_info *fbi; void *addr; @@ -1410,7 +1410,7 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) } #ifdef CONFIG_FB_PXA_PARAMETERS -static int __devinit parse_opt_mode(struct device *dev, const char *this_opt) +static int __init parse_opt_mode(struct device *dev, const char *this_opt) { struct pxafb_mach_info *inf = dev->platform_data; @@ -1469,7 +1469,7 @@ static int __devinit parse_opt_mode(struct device *dev, const char *this_opt) return 0; } -static int __devinit parse_opt(struct device *dev, char *this_opt) +static int __init parse_opt(struct device *dev, char *this_opt) { struct pxafb_mach_info *inf = dev->platform_data; struct pxafb_mode_info *mode = &inf->modes[0]; @@ -1567,7 +1567,7 @@ static int __devinit parse_opt(struct device *dev, char *this_opt) return 0; } -static int __devinit pxafb_parse_options(struct device *dev, char *options) +static int __init pxafb_parse_options(struct device *dev, char *options) { char *this_opt; int ret; @@ -1588,8 +1588,8 @@ static int __devinit pxafb_parse_options(struct device *dev, char *options) static char g_options[256] __devinitdata = ""; -#ifndef MODULE -static int __init pxafb_setup_options(void) +#ifndef CONFIG_MODULES +static int __devinit pxafb_setup_options(void) { char *options = NULL; @@ -1613,7 +1613,7 @@ MODULE_PARM_DESC(options, "LCD parameters (see Documentation/fb/pxafb.txt)"); #define pxafb_setup_options() (0) #endif -static int __devinit pxafb_probe(struct platform_device *dev) +static int __init pxafb_probe(struct platform_device *dev) { struct pxafb_info *fbi; struct pxafb_mach_info *inf; @@ -1685,14 +1685,14 @@ static int __devinit pxafb_probe(struct platform_device *dev) if (r == NULL) { dev_err(&dev->dev, "no I/O memory resource defined\n"); ret = -ENODEV; - goto failed_fbi; + goto failed; } r = request_mem_region(r->start, r->end - r->start + 1, dev->name); if (r == NULL) { dev_err(&dev->dev, "failed to request I/O memory\n"); ret = -EBUSY; - goto failed_fbi; + goto failed; } fbi->mmio_base = ioremap(r->start, r->end - r->start + 1); @@ -1735,17 +1735,8 @@ static int __devinit pxafb_probe(struct platform_device *dev) * This makes sure that our colour bitfield * descriptors are correctly initialised. */ - ret = pxafb_check_var(&fbi->fb.var, &fbi->fb); - if (ret) { - dev_err(&dev->dev, "failed to get suitable mode\n"); - goto failed_free_irq; - } - - ret = pxafb_set_par(&fbi->fb); - if (ret) { - dev_err(&dev->dev, "Failed to set parameters\n"); - goto failed_free_irq; - } + pxafb_check_var(&fbi->fb.var, &fbi->fb); + pxafb_set_par(&fbi->fb); platform_set_drvdata(dev, fbi); @@ -1753,7 +1744,7 @@ static int __devinit pxafb_probe(struct platform_device *dev) if (ret < 0) { dev_err(&dev->dev, "Failed to register framebuffer device: %d\n", ret); - goto failed_free_cmap; + goto failed_free_irq; } #ifdef CONFIG_CPU_FREQ @@ -1772,23 +1763,18 @@ static int __devinit pxafb_probe(struct platform_device *dev) return 0; -failed_free_cmap: - if (fbi->fb.cmap.len) - fb_dealloc_cmap(&fbi->fb.cmap); failed_free_irq: free_irq(irq, fbi); +failed_free_res: + release_mem_region(r->start, r->end - r->start + 1); +failed_free_io: + iounmap(fbi->mmio_base); failed_free_mem: dma_free_writecombine(&dev->dev, fbi->map_size, fbi->map_cpu, fbi->map_dma); -failed_free_io: - iounmap(fbi->mmio_base); -failed_free_res: - release_mem_region(r->start, r->end - r->start + 1); -failed_fbi: - clk_put(fbi->clk); +failed: platform_set_drvdata(dev, NULL); kfree(fbi); -failed: return ret; } @@ -1801,7 +1787,7 @@ static struct platform_driver pxafb_driver = { }, }; -static int __init pxafb_init(void) +static int __devinit pxafb_init(void) { if (pxafb_setup_options()) return -EINVAL; diff --git a/trunk/drivers/watchdog/Makefile b/trunk/drivers/watchdog/Makefile index 25b352b664d9..8662a6b7a30b 100644 --- a/trunk/drivers/watchdog/Makefile +++ b/trunk/drivers/watchdog/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o +CFLAGS_hpwdt.o += -O obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 76e5b7386af9..4f0f22b020ea 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -529,7 +529,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */ /* Clear master flag /before/ clearing selector flag. */ - wmb(); + rmb(); #endif pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); while (pending_words != 0) { diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 10d8a0aa871a..470c10ceb0fb 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -931,16 +931,8 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) struct gendisk *disk; int ret; int part; - int perm = 0; - if (file->f_mode & FMODE_READ) - perm |= MAY_READ; - if (file->f_mode & FMODE_WRITE) - perm |= MAY_WRITE; - /* - * hooks: /n/, see "layering violations". - */ - ret = devcgroup_inode_permission(bdev->bd_inode, perm); + ret = devcgroup_inode_permission(bdev->bd_inode, file->f_mode); if (ret != 0) return ret; diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 0f51c0f7c266..a073f3f4f013 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -821,7 +821,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) * contents - it is a noop if I/O is still in * flight on potentially older contents. */ - ll_rw_block(SWRITE_SYNC, 1, &bh); + ll_rw_block(SWRITE, 1, &bh); brelse(bh); spin_lock(lock); } @@ -2940,19 +2940,16 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) for (i = 0; i < nr; i++) { struct buffer_head *bh = bhs[i]; - if (rw == SWRITE || rw == SWRITE_SYNC) + if (rw == SWRITE) lock_buffer(bh); else if (test_set_buffer_locked(bh)) continue; - if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC) { + if (rw == WRITE || rw == SWRITE) { if (test_clear_buffer_dirty(bh)) { bh->b_end_io = end_buffer_write_sync; get_bh(bh); - if (rw == SWRITE_SYNC) - submit_bh(WRITE_SYNC, bh); - else - submit_bh(WRITE, bh); + submit_bh(WRITE, bh); continue; } } else { @@ -2981,7 +2978,7 @@ int sync_dirty_buffer(struct buffer_head *bh) if (test_clear_buffer_dirty(bh)) { get_bh(bh); bh->b_end_io = end_buffer_write_sync; - ret = submit_bh(WRITE_SYNC, bh); + ret = submit_bh(WRITE, bh); wait_on_buffer(bh); if (buffer_eopnotsupp(bh)) { clear_buffer_eopnotsupp(bh); diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 6068c25b393c..3ee588d5f585 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -107,10 +106,9 @@ static void dentry_lru_remove(struct dentry *dentry) /* * Release the dentry's inode, using the filesystem * d_iput() operation if defined. + * Called with dcache_lock and per dentry lock held, drops both. */ static void dentry_iput(struct dentry * dentry) - __releases(dentry->d_lock) - __releases(dcache_lock) { struct inode *inode = dentry->d_inode; if (inode) { @@ -134,13 +132,12 @@ static void dentry_iput(struct dentry * dentry) * d_kill - kill dentry and return parent * @dentry: dentry to kill * - * The dentry must already be unhashed and removed from the LRU. + * Called with dcache_lock and d_lock, releases both. The dentry must + * already be unhashed and removed from the LRU. * * If this is the root of the dentry tree, return NULL. */ static struct dentry *d_kill(struct dentry *dentry) - __releases(dentry->d_lock) - __releases(dcache_lock) { struct dentry *parent; @@ -386,11 +383,11 @@ void d_prune_aliases(struct inode *inode) * Try to prune ancestors as well. This is necessary to prevent * quadratic behavior of shrink_dcache_parent(), but is also expected * to be beneficial in reducing dentry cache fragmentation. + * + * Called with dcache_lock, drops it and then regains. + * Called with dentry->d_lock held, drops it. */ static void prune_one_dentry(struct dentry * dentry) - __releases(dentry->d_lock) - __releases(dcache_lock) - __acquires(dcache_lock) { __d_drop(dentry); dentry = d_kill(dentry); @@ -1607,9 +1604,10 @@ static int d_isparent(struct dentry *p1, struct dentry *p2) * * Note: If ever the locking in lock_rename() changes, then please * remember to update this too... + * + * On return, dcache_lock will have been unlocked. */ static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) - __releases(dcache_lock) { struct mutex *m1 = NULL, *m2 = NULL; struct dentry *ret; @@ -1745,9 +1743,11 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) shouldnt_be_hashed: spin_unlock(&dcache_lock); BUG(); + goto shouldnt_be_hashed; } -static int prepend(char **buffer, int *buflen, const char *str, int namelen) +static int prepend(char **buffer, int *buflen, const char *str, + int namelen) { *buflen -= namelen; if (*buflen < 0) @@ -1757,13 +1757,8 @@ static int prepend(char **buffer, int *buflen, const char *str, int namelen) return 0; } -static int prepend_name(char **buffer, int *buflen, struct qstr *name) -{ - return prepend(buffer, buflen, name->name, name->len); -} - /** - * __d_path - return the path of a dentry + * d_path - return the path of a dentry * @path: the dentry/vfsmount to report * @root: root vfsmnt/dentry (may be modified by this function) * @buffer: buffer to return value in @@ -1784,10 +1779,9 @@ char *__d_path(const struct path *path, struct path *root, { struct dentry *dentry = path->dentry; struct vfsmount *vfsmnt = path->mnt; - char *end = buffer + buflen; - char *retval; + char * end = buffer+buflen; + char * retval; - spin_lock(&vfsmount_lock); prepend(&end, &buflen, "\0", 1); if (!IS_ROOT(dentry) && d_unhashed(dentry) && (prepend(&end, &buflen, " (deleted)", 10) != 0)) @@ -1806,37 +1800,38 @@ char *__d_path(const struct path *path, struct path *root, break; if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { /* Global root? */ + spin_lock(&vfsmount_lock); if (vfsmnt->mnt_parent == vfsmnt) { + spin_unlock(&vfsmount_lock); goto global_root; } dentry = vfsmnt->mnt_mountpoint; vfsmnt = vfsmnt->mnt_parent; + spin_unlock(&vfsmount_lock); continue; } parent = dentry->d_parent; prefetch(parent); - if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) || + if ((prepend(&end, &buflen, dentry->d_name.name, + dentry->d_name.len) != 0) || (prepend(&end, &buflen, "/", 1) != 0)) goto Elong; retval = end; dentry = parent; } -out: - spin_unlock(&vfsmount_lock); return retval; global_root: retval += 1; /* hit the slash */ - if (prepend_name(&retval, &buflen, &dentry->d_name) != 0) + if (prepend(&retval, &buflen, dentry->d_name.name, + dentry->d_name.len) != 0) goto Elong; root->mnt = vfsmnt; root->dentry = dentry; - goto out; - + return retval; Elong: - retval = ERR_PTR(-ENAMETOOLONG); - goto out; + return ERR_PTR(-ENAMETOOLONG); } /** @@ -1850,9 +1845,9 @@ char *__d_path(const struct path *path, struct path *root, * * Returns the buffer or an error code if the path was too long. * - * "buflen" should be positive. + * "buflen" should be positive. Caller holds the dcache_lock. */ -char *d_path(const struct path *path, char *buf, int buflen) +char *d_path(struct path *path, char *buf, int buflen) { char *res; struct path root; @@ -1920,11 +1915,16 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen) retval = end-1; *retval = '/'; - while (!IS_ROOT(dentry)) { - struct dentry *parent = dentry->d_parent; + for (;;) { + struct dentry *parent; + if (IS_ROOT(dentry)) + break; + parent = dentry->d_parent; prefetch(parent); - if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) || + + if ((prepend(&end, &buflen, dentry->d_name.name, + dentry->d_name.len) != 0) || (prepend(&end, &buflen, "/", 1) != 0)) goto Elong; @@ -1975,7 +1975,7 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) error = -ENOENT; /* Has the current directory has been unlinked? */ spin_lock(&dcache_lock); - if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) { + if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { unsigned long len; struct path tmp = root; char * cwd; diff --git a/trunk/fs/ext4/resize.c b/trunk/fs/ext4/resize.c index 9ff7b1c04239..9ecb92f68543 100644 --- a/trunk/fs/ext4/resize.c +++ b/trunk/fs/ext4/resize.c @@ -855,8 +855,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) */ /* Update group descriptor block for new group */ - gdp = (struct ext4_group_desc *)((char *)primary->b_data + - gdb_off * EXT4_DESC_SIZE(sb)); + gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ diff --git a/trunk/fs/gfs2/bmap.c b/trunk/fs/gfs2/bmap.c index bec76b1c2bb0..c19184f2e70e 100644 --- a/trunk/fs/gfs2/bmap.c +++ b/trunk/fs/gfs2/bmap.c @@ -246,11 +246,15 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block, } -static inline unsigned int metapath_branch_start(const struct metapath *mp) +static inline unsigned int zero_metapath_length(const struct metapath *mp, + unsigned height) { - if (mp->mp_list[0] == 0) - return 2; - return 1; + unsigned int i; + for (i = 0; i < height - 1; i++) { + if (mp->mp_list[i] != 0) + return i; + } + return height; } /** @@ -432,7 +436,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, struct gfs2_sbd *sdp = GFS2_SB(inode); struct buffer_head *dibh = mp->mp_bh[0]; u64 bn, dblock = 0; - unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0; + unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0; unsigned dblks = 0; unsigned ptrs_per_blk; const unsigned end_of_metadata = height - 1; @@ -467,8 +471,9 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, /* Building up tree height */ state = ALLOC_GROW_HEIGHT; iblks = height - ip->i_height; - branch_start = metapath_branch_start(mp); - iblks += (height - branch_start); + zmpl = zero_metapath_length(mp, height); + iblks -= zmpl; + iblks += height; } } @@ -504,13 +509,13 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, sizeof(struct gfs2_meta_header)); *ptr = zero_bn; state = ALLOC_GROW_DEPTH; - for(i = branch_start; i < height; i++) { + for(i = zmpl; i < height; i++) { if (mp->mp_bh[i] == NULL) break; brelse(mp->mp_bh[i]); mp->mp_bh[i] = NULL; } - i = branch_start; + i = zmpl; } if (n == 0) break; diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 3401628d742b..6387523a3153 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -195,7 +195,7 @@ static u32 gfs2_bitfit(const u8 *buffer, unsigned int buflen, u32 goal, depending on architecture. I've experimented with several ways of writing this section such as using an else before the goto but this one seems to be the fastest. */ - while ((unsigned char *)plong < end - sizeof(unsigned long)) { + while ((unsigned char *)plong < end - 1) { prefetch(plong + 1); if (((*plong) & LBITMASK) != lskipval) break; diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index dce8c747371c..11dbf08651b7 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -561,6 +561,9 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) /* insert into file's list */ fl->fl_next = *pos; *pos = fl; + + if (fl->fl_ops && fl->fl_ops->fl_insert) + fl->fl_ops->fl_insert(fl); } /* @@ -583,6 +586,9 @@ static void locks_delete_lock(struct file_lock **thisfl_p) fl->fl_fasync = NULL; } + if (fl->fl_ops && fl->fl_ops->fl_remove) + fl->fl_ops->fl_remove(fl); + if (fl->fl_nspid) { put_pid(fl->fl_nspid); fl->fl_nspid = NULL; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 01e67dddcc3d..c7e43536c49a 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -581,13 +581,15 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd int result; /* make sure the stuff we saved doesn't go away */ - path_get(&save); + dget(save.dentry); + mntget(save.mnt); result = __link_path_walk(name, nd); if (result == -ESTALE) { /* nd->path had been dropped */ nd->path = save; - path_get(&nd->path); + dget(nd->path.dentry); + mntget(nd->path.mnt); nd->flags |= LOOKUP_REVAL; result = __link_path_walk(name, nd); } @@ -1214,9 +1216,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, nd->flags = flags; nd->depth = 0; - nd->path.dentry = dentry; - nd->path.mnt = mnt; - path_get(&nd->path); + nd->path.mnt = mntget(mnt); + nd->path.dentry = dget(dentry); retval = path_walk(name, nd); if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && @@ -2856,17 +2857,16 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) { struct nameidata nd; void *cookie; - int res; nd.depth = 0; cookie = dentry->d_inode->i_op->follow_link(dentry, &nd); - if (IS_ERR(cookie)) - return PTR_ERR(cookie); - - res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); - if (dentry->d_inode->i_op->put_link) - dentry->d_inode->i_op->put_link(dentry, &nd, cookie); - return res; + if (!IS_ERR(cookie)) { + int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); + if (dentry->d_inode->i_op->put_link) + dentry->d_inode->i_op->put_link(dentry, &nd, cookie); + cookie = ERR_PTR(res); + } + return PTR_ERR(cookie); } int vfs_follow_link(struct nameidata *nd, const char *link) diff --git a/trunk/fs/nfs/mount_clnt.c b/trunk/fs/nfs/mount_clnt.c index 779d2eb649c5..49c7cd0502cc 100644 --- a/trunk/fs/nfs/mount_clnt.c +++ b/trunk/fs/nfs/mount_clnt.c @@ -130,11 +130,10 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res) { struct nfs_fh *fh = res->fh; - unsigned size; if ((res->status = ntohl(*p++)) == 0) { - size = ntohl(*p++); - if (size <= NFS3_FHSIZE && size != 0) { + int size = ntohl(*p++); + if (size <= NFS3_FHSIZE) { fh->size = size; memcpy(fh->data, p, size); } else diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 614efeed5437..2a4a024a4e7b 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -1216,6 +1216,8 @@ static int nfs_validate_mount_data(void *options, { struct nfs_mount_data *data = (struct nfs_mount_data *)options; + memset(args, 0, sizeof(*args)); + if (data == NULL) goto out_no_data; @@ -1249,13 +1251,13 @@ static int nfs_validate_mount_data(void *options, case 5: memset(data->context, 0, sizeof(data->context)); case 6: - if (data->flags & NFS_MOUNT_VER3) { - if (data->root.size > NFS3_FHSIZE || data->root.size == 0) - goto out_invalid_fh; + if (data->flags & NFS_MOUNT_VER3) mntfh->size = data->root.size; - } else + else mntfh->size = NFS2_FHSIZE; + if (mntfh->size > sizeof(mntfh->data)) + goto out_invalid_fh; memcpy(mntfh->data, data->root.data, mntfh->size); if (mntfh->size < sizeof(mntfh->data)) @@ -1583,29 +1585,24 @@ static int nfs_get_sb(struct file_system_type *fs_type, { struct nfs_server *server = NULL; struct super_block *s; - struct nfs_parsed_mount_data *data; - struct nfs_fh *mntfh; + struct nfs_fh mntfh; + struct nfs_parsed_mount_data data; struct dentry *mntroot; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; struct nfs_sb_mountdata sb_mntdata = { .mntflags = flags, }; - int error = -ENOMEM; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); - if (data == NULL || mntfh == NULL) - goto out_free_fh; + int error; - security_init_mnt_opts(&data->lsm_opts); + security_init_mnt_opts(&data.lsm_opts); /* Validate the mount data */ - error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name); + error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); if (error < 0) goto out; /* Get a volume representation */ - server = nfs_create_server(data, mntfh); + server = nfs_create_server(&data, &mntfh); if (IS_ERR(server)) { error = PTR_ERR(server); goto out; @@ -1633,16 +1630,16 @@ static int nfs_get_sb(struct file_system_type *fs_type, if (!s->s_root) { /* initial superblock/root creation */ - nfs_fill_super(s, data); + nfs_fill_super(s, &data); } - mntroot = nfs_get_root(s, mntfh); + mntroot = nfs_get_root(s, &mntfh); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; } - error = security_sb_set_mnt_opts(s, &data->lsm_opts); + error = security_sb_set_mnt_opts(s, &data.lsm_opts); if (error) goto error_splat_root; @@ -1652,12 +1649,9 @@ static int nfs_get_sb(struct file_system_type *fs_type, error = 0; out: - kfree(data->nfs_server.hostname); - kfree(data->mount_server.hostname); - security_free_mnt_opts(&data->lsm_opts); -out_free_fh: - kfree(mntfh); - kfree(data); + kfree(data.nfs_server.hostname); + kfree(data.mount_server.hostname); + security_free_mnt_opts(&data.lsm_opts); return error; out_err_nosb: @@ -1806,6 +1800,8 @@ static int nfs4_validate_mount_data(void *options, struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; char *c; + memset(args, 0, sizeof(*args)); + if (data == NULL) goto out_no_data; @@ -1963,31 +1959,26 @@ static int nfs4_validate_mount_data(void *options, static int nfs4_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) { - struct nfs_parsed_mount_data *data; + struct nfs_parsed_mount_data data; struct super_block *s; struct nfs_server *server; - struct nfs_fh *mntfh; + struct nfs_fh mntfh; struct dentry *mntroot; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; struct nfs_sb_mountdata sb_mntdata = { .mntflags = flags, }; - int error = -ENOMEM; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); - if (data == NULL || mntfh == NULL) - goto out_free_fh; + int error; - security_init_mnt_opts(&data->lsm_opts); + security_init_mnt_opts(&data.lsm_opts); /* Validate the mount data */ - error = nfs4_validate_mount_data(raw_data, data, dev_name); + error = nfs4_validate_mount_data(raw_data, &data, dev_name); if (error < 0) goto out; /* Get a volume representation */ - server = nfs4_create_server(data, mntfh); + server = nfs4_create_server(&data, &mntfh); if (IS_ERR(server)) { error = PTR_ERR(server); goto out; @@ -2018,13 +2009,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type, nfs4_fill_super(s); } - mntroot = nfs4_get_root(s, mntfh); + mntroot = nfs4_get_root(s, &mntfh); if (IS_ERR(mntroot)) { error = PTR_ERR(mntroot); goto error_splat_super; } - error = security_sb_set_mnt_opts(s, &data->lsm_opts); + error = security_sb_set_mnt_opts(s, &data.lsm_opts); if (error) goto error_splat_root; @@ -2034,13 +2025,10 @@ static int nfs4_get_sb(struct file_system_type *fs_type, error = 0; out: - kfree(data->client_address); - kfree(data->nfs_server.export_path); - kfree(data->nfs_server.hostname); - security_free_mnt_opts(&data->lsm_opts); -out_free_fh: - kfree(mntfh); - kfree(data); + kfree(data.client_address); + kfree(data.nfs_server.export_path); + kfree(data.nfs_server.hostname); + security_free_mnt_opts(&data.lsm_opts); return error; out_free: diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index f333848fd3be..6d8ace3e3259 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -739,13 +739,12 @@ int nfs_updatepage(struct file *file, struct page *page, } status = nfs_writepage_setup(ctx, page, offset, count); - if (status < 0) - nfs_set_pageerror(page); - else - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(page); dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", status, (long long)i_size_read(inode)); + if (status < 0) + nfs_set_pageerror(page); return status; } diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index 700f4e0d9572..ec228bc9f882 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -1003,7 +1003,8 @@ struct file *create_write_pipe(void) void free_write_pipe(struct file *f) { free_pipe_info(f->f_dentry->d_inode); - path_put(&f->f_path); + dput(f->f_path.dentry); + mntput(f->f_path.mnt); put_filp(f); } @@ -1014,8 +1015,8 @@ struct file *create_read_pipe(struct file *wrf) return ERR_PTR(-ENFILE); /* Grab pipe from the writer */ - f->f_path = wrf->f_path; - path_get(&wrf->f_path); + f->f_path.mnt = mntget(wrf->f_path.mnt); + f->f_path.dentry = dget(wrf->f_path.dentry); f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; f->f_pos = 0; @@ -1067,7 +1068,8 @@ int do_pipe(int *fd) err_fdr: put_unused_fd(fdr); err_read_pipe: - path_put(&fr->f_path); + dput(fr->f_dentry); + mntput(fr->f_vfsmnt); put_filp(fr); err_write_pipe: free_write_pipe(fw); diff --git a/trunk/fs/select.c b/trunk/fs/select.c index da0e88201c3a..8dda969614a9 100644 --- a/trunk/fs/select.c +++ b/trunk/fs/select.c @@ -249,6 +249,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) retval++; } } + cond_resched(); } if (res_in) *rinp = res_in; @@ -256,7 +257,6 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) *routp = res_out; if (res_ex) *rexp = res_ex; - cond_resched(); } wait = NULL; if (retval || !*timeout || signal_pending(current)) diff --git a/trunk/fs/udf/super.c b/trunk/fs/udf/super.c index 44cc702f96cc..7a5f69be6ac2 100644 --- a/trunk/fs/udf/super.c +++ b/trunk/fs/udf/super.c @@ -682,26 +682,38 @@ static int udf_vrs(struct super_block *sb, int silent) /* * Check whether there is an anchor block in the given block */ -static int udf_check_anchor_block(struct super_block *sb, sector_t block) +static int udf_check_anchor_block(struct super_block *sb, sector_t block, + bool varconv) { - struct buffer_head *bh; + struct buffer_head *bh = NULL; + tag *t; uint16_t ident; + uint32_t location; - if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && - udf_fixed_to_variable(block) >= - sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) - return 0; + if (varconv) { + if (udf_fixed_to_variable(block) >= + sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) + return 0; + bh = sb_bread(sb, udf_fixed_to_variable(block)); + } + else + bh = sb_bread(sb, block); - bh = udf_read_tagged(sb, block, block, &ident); if (!bh) return 0; - brelse(bh); - return ident == TAG_IDENT_AVDP; + t = (tag *)bh->b_data; + ident = le16_to_cpu(t->tagIdent); + location = le32_to_cpu(t->tagLocation); + brelse(bh); + if (ident != TAG_IDENT_AVDP) + return 0; + return location == block; } /* Search for an anchor volume descriptor pointer */ -static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) +static sector_t udf_scan_anchors(struct super_block *sb, bool varconv, + sector_t lastblock) { sector_t last[6]; int i; @@ -727,7 +739,7 @@ static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) sb->s_blocksize_bits) continue; - if (udf_check_anchor_block(sb, last[i])) { + if (udf_check_anchor_block(sb, last[i], varconv)) { sbi->s_anchor[0] = last[i]; sbi->s_anchor[1] = last[i] - 256; return last[i]; @@ -736,17 +748,17 @@ static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) if (last[i] < 256) continue; - if (udf_check_anchor_block(sb, last[i] - 256)) { + if (udf_check_anchor_block(sb, last[i] - 256, varconv)) { sbi->s_anchor[1] = last[i] - 256; return last[i]; } } - if (udf_check_anchor_block(sb, sbi->s_session + 256)) { + if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) { sbi->s_anchor[0] = sbi->s_session + 256; return last[0]; } - if (udf_check_anchor_block(sb, sbi->s_session + 512)) { + if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) { sbi->s_anchor[0] = sbi->s_session + 512; return last[0]; } @@ -768,24 +780,23 @@ static void udf_find_anchor(struct super_block *sb) int i; struct udf_sb_info *sbi = UDF_SB(sb); - lastblock = udf_scan_anchors(sb, sbi->s_last_block); + lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block); if (lastblock) goto check_anchor; /* No anchor found? Try VARCONV conversion of block numbers */ - UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); /* Firstly, we try to not convert number of the last block */ - lastblock = udf_scan_anchors(sb, + lastblock = udf_scan_anchors(sb, 1, udf_variable_to_fixed(sbi->s_last_block)); - if (lastblock) + if (lastblock) { + UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); goto check_anchor; + } /* Secondly, we try with converted number of the last block */ - lastblock = udf_scan_anchors(sb, sbi->s_last_block); - if (!lastblock) { - /* VARCONV didn't help. Clear it. */ - UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); - } + lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block); + if (lastblock) + UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); check_anchor: /* diff --git a/trunk/fs/utimes.c b/trunk/fs/utimes.c index b6b664e7145e..af059d5cb485 100644 --- a/trunk/fs/utimes.c +++ b/trunk/fs/utimes.c @@ -40,9 +40,14 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) #endif +static bool nsec_special(long nsec) +{ + return nsec == UTIME_OMIT || nsec == UTIME_NOW; +} + static bool nsec_valid(long nsec) { - if (nsec == UTIME_OMIT || nsec == UTIME_NOW) + if (nsec_special(nsec)) return true; return nsec >= 0 && nsec <= 999999999; @@ -97,11 +102,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags if (error) goto dput_and_out; - if (times && times[0].tv_nsec == UTIME_NOW && - times[1].tv_nsec == UTIME_NOW) - times = NULL; - - /* In most cases, the checks are done in inode_change_ok() */ + /* Don't worry, the checks are done in inode_change_ok() */ newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; if (times) { error = -EPERM; @@ -123,34 +124,28 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; newattrs.ia_valid |= ATTR_MTIME_SET; } + } - /* - * For the UTIME_OMIT/UTIME_NOW and UTIME_NOW/UTIME_OMIT - * cases, we need to make an extra check that is not done by - * inode_change_ok(). - */ - if (((times[0].tv_nsec == UTIME_NOW && - times[1].tv_nsec == UTIME_OMIT) - || - (times[0].tv_nsec == UTIME_OMIT && - times[1].tv_nsec == UTIME_NOW)) - && !is_owner_or_cap(inode)) - goto mnt_drop_write_and_out; - } else { - - /* - * If times is NULL (or both times are UTIME_NOW), - * then we need to check permissions, because - * inode_change_ok() won't do it. - */ + /* + * If times is NULL or both times are either UTIME_OMIT or + * UTIME_NOW, then need to check permissions, because + * inode_change_ok() won't do it. + */ + if (!times || (nsec_special(times[0].tv_nsec) && + nsec_special(times[1].tv_nsec))) { error = -EACCES; if (IS_IMMUTABLE(inode)) goto mnt_drop_write_and_out; if (!is_owner_or_cap(inode)) { - error = permission(inode, MAY_WRITE, NULL); - if (error) - goto mnt_drop_write_and_out; + if (f) { + if (!(f->f_mode & FMODE_WRITE)) + goto mnt_drop_write_and_out; + } else { + error = vfs_permission(&nd, MAY_WRITE); + if (error) + goto mnt_drop_write_and_out; + } } } mutex_lock(&inode->i_mutex); @@ -174,6 +169,14 @@ asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __ if (utimes) { if (copy_from_user(&tstimes, utimes, sizeof(tstimes))) return -EFAULT; + if ((tstimes[0].tv_nsec == UTIME_OMIT || + tstimes[0].tv_nsec == UTIME_NOW) && + tstimes[0].tv_sec != 0) + return -EINVAL; + if ((tstimes[1].tv_nsec == UTIME_OMIT || + tstimes[1].tv_nsec == UTIME_NOW) && + tstimes[1].tv_sec != 0) + return -EINVAL; /* Nothing to do, we must not even check the path. */ if (tstimes[0].tv_nsec == UTIME_OMIT && diff --git a/trunk/include/asm-alpha/core_mcpcia.h b/trunk/include/asm-alpha/core_mcpcia.h index acf55b483472..525b4f6a7ace 100644 --- a/trunk/include/asm-alpha/core_mcpcia.h +++ b/trunk/include/asm-alpha/core_mcpcia.h @@ -261,7 +261,7 @@ struct el_MCPCIA_uncorrected_frame_mcheck { } #endif -extern inline int __mcpcia_is_mmio(unsigned long addr) +static inline int __mcpcia_is_mmio(unsigned long addr) { return (addr & 0x80000000UL) == 0; } diff --git a/trunk/include/asm-alpha/core_t2.h b/trunk/include/asm-alpha/core_t2.h index 46bfff58f670..90e6b5d6c214 100644 --- a/trunk/include/asm-alpha/core_t2.h +++ b/trunk/include/asm-alpha/core_t2.h @@ -356,13 +356,13 @@ struct el_t2_frame_corrected { #define vip volatile int * #define vuip volatile unsigned int * -extern inline u8 t2_inb(unsigned long addr) +static inline u8 t2_inb(unsigned long addr) { long result = *(vip) ((addr << 5) + T2_IO + 0x00); return __kernel_extbl(result, addr & 3); } -extern inline void t2_outb(u8 b, unsigned long addr) +static inline void t2_outb(u8 b, unsigned long addr) { unsigned long w; @@ -371,13 +371,13 @@ extern inline void t2_outb(u8 b, unsigned long addr) mb(); } -extern inline u16 t2_inw(unsigned long addr) +static inline u16 t2_inw(unsigned long addr) { long result = *(vip) ((addr << 5) + T2_IO + 0x08); return __kernel_extwl(result, addr & 3); } -extern inline void t2_outw(u16 b, unsigned long addr) +static inline void t2_outw(u16 b, unsigned long addr) { unsigned long w; @@ -386,12 +386,12 @@ extern inline void t2_outw(u16 b, unsigned long addr) mb(); } -extern inline u32 t2_inl(unsigned long addr) +static inline u32 t2_inl(unsigned long addr) { return *(vuip) ((addr << 5) + T2_IO + 0x18); } -extern inline void t2_outl(u32 b, unsigned long addr) +static inline void t2_outl(u32 b, unsigned long addr) { *(vuip) ((addr << 5) + T2_IO + 0x18) = b; mb(); @@ -435,7 +435,7 @@ extern inline void t2_outl(u32 b, unsigned long addr) set_hae(msb); \ } -extern spinlock_t t2_hae_lock; +static DEFINE_SPINLOCK(t2_hae_lock); /* * NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since diff --git a/trunk/include/asm-alpha/io.h b/trunk/include/asm-alpha/io.h index e971ab000f95..38f18cf18c9d 100644 --- a/trunk/include/asm-alpha/io.h +++ b/trunk/include/asm-alpha/io.h @@ -35,7 +35,7 @@ * register not being up-to-date with respect to the hardware * value. */ -extern inline void __set_hae(unsigned long new_hae) +static inline void __set_hae(unsigned long new_hae) { unsigned long flags; local_irq_save(flags); @@ -49,7 +49,7 @@ extern inline void __set_hae(unsigned long new_hae) local_irq_restore(flags); } -extern inline void set_hae(unsigned long new_hae) +static inline void set_hae(unsigned long new_hae) { if (new_hae != alpha_mv.hae_cache) __set_hae(new_hae); @@ -176,7 +176,7 @@ REMAP2(u64, writeq, volatile) #undef REMAP1 #undef REMAP2 -extern inline void __iomem *generic_ioportmap(unsigned long a) +static inline void __iomem *generic_ioportmap(unsigned long a) { return alpha_mv.mv_ioportmap(a); } diff --git a/trunk/include/asm-alpha/mmu_context.h b/trunk/include/asm-alpha/mmu_context.h index 86c08a02d239..6a5be1f7debf 100644 --- a/trunk/include/asm-alpha/mmu_context.h +++ b/trunk/include/asm-alpha/mmu_context.h @@ -23,7 +23,7 @@ #endif -static inline unsigned long +extern inline unsigned long __reload_thread(struct pcb_struct *pcb) { register unsigned long a0 __asm__("$16"); @@ -114,7 +114,7 @@ extern unsigned long last_asn; #define __MMU_EXTERN_INLINE #endif -extern inline unsigned long +static inline unsigned long __get_new_mm_context(struct mm_struct *mm, long cpu) { unsigned long asn = cpu_last_asn(cpu); @@ -226,7 +226,7 @@ ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm) # endif #endif -static inline int +extern inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { int i; diff --git a/trunk/include/asm-alpha/percpu.h b/trunk/include/asm-alpha/percpu.h index 3495e8e00d70..48348fe34c19 100644 --- a/trunk/include/asm-alpha/percpu.h +++ b/trunk/include/asm-alpha/percpu.h @@ -1,78 +1,6 @@ #ifndef __ALPHA_PERCPU_H #define __ALPHA_PERCPU_H -#include -#include -/* - * Determine the real variable name from the name visible in the - * kernel sources. - */ -#define per_cpu_var(var) per_cpu__##var - -#ifdef CONFIG_SMP - -/* - * per_cpu_offset() is the offset that has to be added to a - * percpu variable to get to the instance for a certain processor. - */ -extern unsigned long __per_cpu_offset[NR_CPUS]; - -#define per_cpu_offset(x) (__per_cpu_offset[x]) - -#define __my_cpu_offset per_cpu_offset(raw_smp_processor_id()) -#ifdef CONFIG_DEBUG_PREEMPT -#define my_cpu_offset per_cpu_offset(smp_processor_id()) -#else -#define my_cpu_offset __my_cpu_offset -#endif - -#ifndef MODULE -#define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset)) -#define PER_CPU_ATTRIBUTES -#else -/* - * To calculate addresses of locally defined variables, GCC uses 32-bit - * displacement from the GP. Which doesn't work for per cpu variables in - * modules, as an offset to the kernel per cpu area is way above 4G. - * - * This forces allocation of a GOT entry for per cpu variable using - * ldq instruction with a 'literal' relocation. - */ -#define SHIFT_PERCPU_PTR(var, offset) ({ \ - extern int simple_identifier_##var(void); \ - unsigned long __ptr, tmp_gp; \ - asm ( "br %1, 1f \n\ - 1: ldgp %1, 0(%1) \n\ - ldq %0, per_cpu__" #var"(%1)\t!literal" \ - : "=&r"(__ptr), "=&r"(tmp_gp)); \ - (typeof(&per_cpu_var(var)))(__ptr + (offset)); }) - -#define PER_CPU_ATTRIBUTES __used - -#endif /* MODULE */ - -/* - * A percpu variable may point to a discarded regions. The following are - * established ways to produce a usable pointer from the percpu variable - * offset. - */ -#define per_cpu(var, cpu) \ - (*SHIFT_PERCPU_PTR(var, per_cpu_offset(cpu))) -#define __get_cpu_var(var) \ - (*SHIFT_PERCPU_PTR(var, my_cpu_offset)) -#define __raw_get_cpu_var(var) \ - (*SHIFT_PERCPU_PTR(var, __my_cpu_offset)) - -#else /* ! SMP */ - -#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu_var(var))) -#define __get_cpu_var(var) per_cpu_var(var) -#define __raw_get_cpu_var(var) per_cpu_var(var) - -#define PER_CPU_ATTRIBUTES - -#endif /* SMP */ - -#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name) +#include #endif /* __ALPHA_PERCPU_H */ diff --git a/trunk/include/asm-alpha/system.h b/trunk/include/asm-alpha/system.h index afe20fa58c99..ed221d6408fc 100644 --- a/trunk/include/asm-alpha/system.h +++ b/trunk/include/asm-alpha/system.h @@ -184,7 +184,7 @@ enum amask_enum { __amask; }) #define __CALL_PAL_R0(NAME, TYPE) \ -extern inline TYPE NAME(void) \ +static inline TYPE NAME(void) \ { \ register TYPE __r0 __asm__("$0"); \ __asm__ __volatile__( \ @@ -196,7 +196,7 @@ extern inline TYPE NAME(void) \ } #define __CALL_PAL_W1(NAME, TYPE0) \ -extern inline void NAME(TYPE0 arg0) \ +static inline void NAME(TYPE0 arg0) \ { \ register TYPE0 __r16 __asm__("$16") = arg0; \ __asm__ __volatile__( \ @@ -207,7 +207,7 @@ extern inline void NAME(TYPE0 arg0) \ } #define __CALL_PAL_W2(NAME, TYPE0, TYPE1) \ -extern inline void NAME(TYPE0 arg0, TYPE1 arg1) \ +static inline void NAME(TYPE0 arg0, TYPE1 arg1) \ { \ register TYPE0 __r16 __asm__("$16") = arg0; \ register TYPE1 __r17 __asm__("$17") = arg1; \ @@ -219,7 +219,7 @@ extern inline void NAME(TYPE0 arg0, TYPE1 arg1) \ } #define __CALL_PAL_RW1(NAME, RTYPE, TYPE0) \ -extern inline RTYPE NAME(TYPE0 arg0) \ +static inline RTYPE NAME(TYPE0 arg0) \ { \ register RTYPE __r0 __asm__("$0"); \ register TYPE0 __r16 __asm__("$16") = arg0; \ @@ -232,7 +232,7 @@ extern inline RTYPE NAME(TYPE0 arg0) \ } #define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1) \ -extern inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1) \ +static inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1) \ { \ register RTYPE __r0 __asm__("$0"); \ register TYPE0 __r16 __asm__("$16") = arg0; \ diff --git a/trunk/include/asm-alpha/vga.h b/trunk/include/asm-alpha/vga.h index c00106bac521..e8df1e7aae6b 100644 --- a/trunk/include/asm-alpha/vga.h +++ b/trunk/include/asm-alpha/vga.h @@ -13,7 +13,7 @@ #define VT_BUF_HAVE_MEMSETW #define VT_BUF_HAVE_MEMCPYW -static inline void scr_writew(u16 val, volatile u16 *addr) +extern inline void scr_writew(u16 val, volatile u16 *addr) { if (__is_ioaddr(addr)) __raw_writew(val, (volatile u16 __iomem *) addr); @@ -21,7 +21,7 @@ static inline void scr_writew(u16 val, volatile u16 *addr) *addr = val; } -static inline u16 scr_readw(volatile const u16 *addr) +extern inline u16 scr_readw(volatile const u16 *addr) { if (__is_ioaddr(addr)) return __raw_readw((volatile const u16 __iomem *) addr); @@ -29,7 +29,7 @@ static inline u16 scr_readw(volatile const u16 *addr) return *addr; } -static inline void scr_memsetw(u16 *s, u16 c, unsigned int count) +extern inline void scr_memsetw(u16 *s, u16 c, unsigned int count) { if (__is_ioaddr(s)) memsetw_io((u16 __iomem *) s, c, count); diff --git a/trunk/include/asm-arm/arch-omap/board-2430sdp.h b/trunk/include/asm-arm/arch-omap/board-2430sdp.h index c7db9004ec31..e9c65ce3cb12 100644 --- a/trunk/include/asm-arm/arch-omap/board-2430sdp.h +++ b/trunk/include/asm-arm/arch-omap/board-2430sdp.h @@ -36,4 +36,9 @@ #define TWL4030_IRQNUM INT_24XX_SYS_NIRQ +/* TWL4030 Primary Interrupt Handler (PIH) interrupts */ +#define IH_TWL4030_BASE IH_BOARD_BASE +#define IH_TWL4030_END (IH_TWL4030_BASE+8) +#define NR_IRQS (IH_TWL4030_END) + #endif /* __ASM_ARCH_OMAP_2430SDP_H */ diff --git a/trunk/include/asm-arm/arch-omap/board-h3.h b/trunk/include/asm-arm/arch-omap/board-h3.h index c5d0f32a40ac..0f6404435ea8 100644 --- a/trunk/include/asm-arm/arch-omap/board-h3.h +++ b/trunk/include/asm-arm/arch-omap/board-h3.h @@ -30,6 +30,12 @@ /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */ #define OMAP1710_ETHR_START 0x04000300 +#define MAXIRQNUM (IH_BOARD_BASE) +#define MAXFIQNUM MAXIRQNUM +#define MAXSWINUM MAXIRQNUM + +#define NR_IRQS (MAXIRQNUM + 1) + extern void h3_mmc_init(void); extern void h3_mmc_slot_cover_handler(void *arg, int state); diff --git a/trunk/include/asm-arm/arch-omap/board-innovator.h b/trunk/include/asm-arm/arch-omap/board-innovator.h index 9ca03dec9d36..56d2c98e143c 100644 --- a/trunk/include/asm-arm/arch-omap/board-innovator.h +++ b/trunk/include/asm-arm/arch-omap/board-innovator.h @@ -36,6 +36,9 @@ #define OMAP1510P1_EMIFS_PRI_VALUE 0x00 #define OMAP1510P1_EMIFF_PRI_VALUE 0x00 +#define NR_FPGA_IRQS 24 +#define NR_IRQS (IH_BOARD_BASE + NR_FPGA_IRQS) + #ifndef __ASSEMBLY__ void fpga_write(unsigned char val, int reg); unsigned char fpga_read(int reg); diff --git a/trunk/include/asm-arm/arch-omap/board-perseus2.h b/trunk/include/asm-arm/arch-omap/board-perseus2.h index d7429cb0f726..eb74420cb439 100644 --- a/trunk/include/asm-arm/arch-omap/board-perseus2.h +++ b/trunk/include/asm-arm/arch-omap/board-perseus2.h @@ -36,4 +36,10 @@ #define OMAP_SDRAM_DEVICE D256M_1X16_4B #endif +#define MAXIRQNUM IH_BOARD_BASE +#define MAXFIQNUM MAXIRQNUM +#define MAXSWINUM MAXIRQNUM + +#define NR_IRQS (MAXIRQNUM + 1) + #endif diff --git a/trunk/include/asm-arm/arch-omap/clock.h b/trunk/include/asm-arm/arch-omap/clock.h index 4c7b3514f71a..12a5e4de9518 100644 --- a/trunk/include/asm-arm/arch-omap/clock.h +++ b/trunk/include/asm-arm/arch-omap/clock.h @@ -33,24 +33,12 @@ struct dpll_data { void __iomem *mult_div1_reg; u32 mult_mask; u32 div1_mask; - u16 last_rounded_m; - u8 last_rounded_n; - unsigned long last_rounded_rate; - unsigned int rate_tolerance; - u16 max_multiplier; - u8 max_divider; - u32 max_tolerance; # if defined(CONFIG_ARCH_OMAP3) - u8 modes; void __iomem *control_reg; u32 enable_mask; u8 auto_recal_bit; u8 recal_en_bit; u8 recal_st_bit; - void __iomem *autoidle_reg; - u32 autoidle_mask; - void __iomem *idlest_reg; - u8 idlest_bit; # endif }; @@ -78,14 +66,11 @@ struct clk { void __iomem *clksel_reg; u32 clksel_mask; const struct clksel *clksel; - struct dpll_data *dpll_data; + const struct dpll_data *dpll_data; #else __u8 rate_offset; __u8 src_offset; #endif -#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) - struct dentry *dent; /* For visible tree hierarchy */ -#endif }; struct cpufreq_frequency_table; diff --git a/trunk/include/asm-arm/arch-omap/common.h b/trunk/include/asm-arm/arch-omap/common.h index 8ac03071f60c..36a3b62d4d8d 100644 --- a/trunk/include/asm-arm/arch-omap/common.h +++ b/trunk/include/asm-arm/arch-omap/common.h @@ -47,23 +47,8 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, } #endif -/* IO bases for various OMAP processors */ -struct omap_globals { - void __iomem *tap; /* Control module ID code */ - void __iomem *sdrc; /* SDRAM Controller */ - void __iomem *sms; /* SDRAM Memory Scheduler */ - void __iomem *ctrl; /* System Control Module */ - void __iomem *prm; /* Power and Reset Management */ - void __iomem *cm; /* Clock Management */ -}; - void omap2_set_globals_242x(void); void omap2_set_globals_243x(void); void omap2_set_globals_343x(void); -/* These get called from omap2_set_globals_xxxx(), do not call these */ -void omap2_set_globals_memory(struct omap_globals *); -void omap2_set_globals_control(struct omap_globals *); -void omap2_set_globals_prcm(struct omap_globals *); - #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/trunk/include/asm-arm/arch-omap/control.h b/trunk/include/asm-arm/arch-omap/control.h index 987553e3eeb9..59c0686f8be7 100644 --- a/trunk/include/asm-arm/arch-omap/control.h +++ b/trunk/include/asm-arm/arch-omap/control.h @@ -167,7 +167,8 @@ #ifndef __ASSEMBLY__ #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -extern void __iomem *omap_ctrl_base_get(void); +extern void omap_ctrl_base_set(u32 base); +extern u32 omap_ctrl_base_get(void); extern u8 omap_ctrl_readb(u16 offset); extern u16 omap_ctrl_readw(u16 offset); extern u32 omap_ctrl_readl(u16 offset); @@ -175,6 +176,7 @@ extern void omap_ctrl_writeb(u8 val, u16 offset); extern void omap_ctrl_writew(u16 val, u16 offset); extern void omap_ctrl_writel(u32 val, u16 offset); #else +#define omap_ctrl_base_set(x) WARN_ON(1) #define omap_ctrl_base_get() 0 #define omap_ctrl_readb(x) 0 #define omap_ctrl_readw(x) 0 diff --git a/trunk/include/asm-arm/arch-omap/cpu.h b/trunk/include/asm-arm/arch-omap/cpu.h index 52db09f83281..e8a4cf52778b 100644 --- a/trunk/include/asm-arm/arch-omap/cpu.h +++ b/trunk/include/asm-arm/arch-omap/cpu.h @@ -3,7 +3,7 @@ * * OMAP cpu type detection * - * Copyright (C) 2004, 2008 Nokia Corporation + * Copyright (C) 2004 Nokia Corporation * * Written by Tony Lindgren * @@ -26,12 +26,6 @@ #ifndef __ASM_ARCH_OMAP_CPU_H #define __ASM_ARCH_OMAP_CPU_H -struct omap_chip_id { - u8 oc; -}; - -#define OMAP_CHIP_INIT(x) { .oc = x } - extern unsigned int system_rev; #define omap2_cpu_rev() ((system_rev >> 12) & 0x0f) @@ -351,33 +345,6 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP2430_REV_ES1_0 0x24300000 #define OMAP3430_REV_ES1_0 0x34300000 #define OMAP3430_REV_ES2_0 0x34301000 -#define OMAP3430_REV_ES2_1 0x34302000 -#define OMAP3430_REV_ES2_2 0x34303000 - -/* - * omap_chip bits - * - * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is - * valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates - * something that is only valid on that particular ES revision. - * - * These bits may be ORed together to indicate structures that are - * available on multiple chip types. - * - * To test whether a particular structure matches the current OMAP chip type, - * use omap_chip_is(). - * - */ -#define CHIP_IS_OMAP2420 (1 << 0) -#define CHIP_IS_OMAP2430 (1 << 1) -#define CHIP_IS_OMAP3430 (1 << 2) -#define CHIP_IS_OMAP3430ES1 (1 << 3) -#define CHIP_IS_OMAP3430ES2 (1 << 4) - -#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) - -int omap_chip_is(struct omap_chip_id oci); - /* * Macro to detect device type i.e. EMU/HS/TST/GP/BAD @@ -395,8 +362,6 @@ int omap_chip_is(struct omap_chip_id oci); #define is_device_type_gp() (get_device_type() == DEVICE_TYPE_GP) #define is_device_type_bad() (get_device_type() == DEVICE_TYPE_BAD) -void omap2_check_revision(void); - -#endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */ +#endif #endif diff --git a/trunk/include/asm-arm/arch-omap/dma.h b/trunk/include/asm-arm/arch-omap/dma.h index f4dcb9587869..24acf090030d 100644 --- a/trunk/include/asm-arm/arch-omap/dma.h +++ b/trunk/include/asm-arm/arch-omap/dma.h @@ -22,128 +22,108 @@ #define __ASM_ARCH_DMA_H /* Hardware registers for omap1 */ -#define OMAP1_DMA_BASE (0xfffed800) - -#define OMAP1_DMA_GCR 0x400 -#define OMAP1_DMA_GSCR 0x404 -#define OMAP1_DMA_GRST 0x408 -#define OMAP1_DMA_HW_ID 0x442 -#define OMAP1_DMA_PCH2_ID 0x444 -#define OMAP1_DMA_PCH0_ID 0x446 -#define OMAP1_DMA_PCH1_ID 0x448 -#define OMAP1_DMA_PCHG_ID 0x44a -#define OMAP1_DMA_PCHD_ID 0x44c -#define OMAP1_DMA_CAPS_0_U 0x44e -#define OMAP1_DMA_CAPS_0_L 0x450 -#define OMAP1_DMA_CAPS_1_U 0x452 -#define OMAP1_DMA_CAPS_1_L 0x454 -#define OMAP1_DMA_CAPS_2 0x456 -#define OMAP1_DMA_CAPS_3 0x458 -#define OMAP1_DMA_CAPS_4 0x45a -#define OMAP1_DMA_PCH2_SR 0x460 -#define OMAP1_DMA_PCH0_SR 0x480 -#define OMAP1_DMA_PCH1_SR 0x482 -#define OMAP1_DMA_PCHD_SR 0x4c0 - -/* Hardware registers for omap2 and omap3 */ -#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000) -#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000) - -#define OMAP_DMA4_REVISION 0x00 -#define OMAP_DMA4_GCR 0x78 -#define OMAP_DMA4_IRQSTATUS_L0 0x08 -#define OMAP_DMA4_IRQSTATUS_L1 0x0c -#define OMAP_DMA4_IRQSTATUS_L2 0x10 -#define OMAP_DMA4_IRQSTATUS_L3 0x14 -#define OMAP_DMA4_IRQENABLE_L0 0x18 -#define OMAP_DMA4_IRQENABLE_L1 0x1c -#define OMAP_DMA4_IRQENABLE_L2 0x20 -#define OMAP_DMA4_IRQENABLE_L3 0x24 -#define OMAP_DMA4_SYSSTATUS 0x28 -#define OMAP_DMA4_OCP_SYSCONFIG 0x2c -#define OMAP_DMA4_CAPS_0 0x64 -#define OMAP_DMA4_CAPS_2 0x6c -#define OMAP_DMA4_CAPS_3 0x70 -#define OMAP_DMA4_CAPS_4 0x74 - -#define OMAP1_LOGICAL_DMA_CH_COUNT 17 -#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */ +#define OMAP_DMA_BASE (0xfffed800) +#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400) +#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404) +#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408) +#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442) +#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444) +#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446) +#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448) +#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a) +#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c) +#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e) +#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450) +#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452) +#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454) +#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456) +#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458) +#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a) +#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460) +#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480) +#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482) +#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0) + +/* Hardware registers for omap2 */ +#if defined(CONFIG_ARCH_OMAP3) +#define OMAP_DMA4_BASE (L4_34XX_BASE + 0x56000) +#else /* CONFIG_ARCH_OMAP2 */ +#define OMAP_DMA4_BASE (L4_24XX_BASE + 0x56000) +#endif + +#define OMAP_DMA4_REVISION (OMAP_DMA4_BASE + 0x00) +#define OMAP_DMA4_GCR_REG (OMAP_DMA4_BASE + 0x78) +#define OMAP_DMA4_IRQSTATUS_L0 (OMAP_DMA4_BASE + 0x08) +#define OMAP_DMA4_IRQSTATUS_L1 (OMAP_DMA4_BASE + 0x0c) +#define OMAP_DMA4_IRQSTATUS_L2 (OMAP_DMA4_BASE + 0x10) +#define OMAP_DMA4_IRQSTATUS_L3 (OMAP_DMA4_BASE + 0x14) +#define OMAP_DMA4_IRQENABLE_L0 (OMAP_DMA4_BASE + 0x18) +#define OMAP_DMA4_IRQENABLE_L1 (OMAP_DMA4_BASE + 0x1c) +#define OMAP_DMA4_IRQENABLE_L2 (OMAP_DMA4_BASE + 0x20) +#define OMAP_DMA4_IRQENABLE_L3 (OMAP_DMA4_BASE + 0x24) +#define OMAP_DMA4_SYSSTATUS (OMAP_DMA4_BASE + 0x28) +#define OMAP_DMA4_OCP_SYSCONFIG (OMAP_DMA4_BASE + 0x2c) +#define OMAP_DMA4_CAPS_0 (OMAP_DMA4_BASE + 0x64) +#define OMAP_DMA4_CAPS_2 (OMAP_DMA4_BASE + 0x6c) +#define OMAP_DMA4_CAPS_3 (OMAP_DMA4_BASE + 0x70) +#define OMAP_DMA4_CAPS_4 (OMAP_DMA4_BASE + 0x74) + +#ifdef CONFIG_ARCH_OMAP1 + +#define OMAP_LOGICAL_DMA_CH_COUNT 17 /* Common channel specific registers for omap1 */ -#define OMAP1_DMA_CH_BASE(n) (0x40 * (n) + 0x00) -#define OMAP1_DMA_CSDP(n) (0x40 * (n) + 0x00) -#define OMAP1_DMA_CCR(n) (0x40 * (n) + 0x02) -#define OMAP1_DMA_CICR(n) (0x40 * (n) + 0x04) -#define OMAP1_DMA_CSR(n) (0x40 * (n) + 0x06) -#define OMAP1_DMA_CEN(n) (0x40 * (n) + 0x10) -#define OMAP1_DMA_CFN(n) (0x40 * (n) + 0x12) -#define OMAP1_DMA_CSFI(n) (0x40 * (n) + 0x14) -#define OMAP1_DMA_CSEI(n) (0x40 * (n) + 0x16) -#define OMAP1_DMA_CPC(n) (0x40 * (n) + 0x18) /* 15xx only */ -#define OMAP1_DMA_CSAC(n) (0x40 * (n) + 0x18) -#define OMAP1_DMA_CDAC(n) (0x40 * (n) + 0x1a) -#define OMAP1_DMA_CDEI(n) (0x40 * (n) + 0x1c) -#define OMAP1_DMA_CDFI(n) (0x40 * (n) + 0x1e) -#define OMAP1_DMA_CLNK_CTRL(n) (0x40 * (n) + 0x28) +#define OMAP_DMA_CSDP_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x00) +#define OMAP_DMA_CCR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x02) +#define OMAP_DMA_CICR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x04) +#define OMAP_DMA_CSR_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x06) +#define OMAP_DMA_CEN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x10) +#define OMAP_DMA_CFN_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x12) +#define OMAP_DMA_CSFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x14) +#define OMAP_DMA_CSEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x16) +#define OMAP_DMA_CSAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x18) +#define OMAP_DMA_CDAC_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1a) +#define OMAP_DMA_CDEI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1c) +#define OMAP_DMA_CDFI_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x1e) +#define OMAP_DMA_CLNK_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x28) + +#else + +#define OMAP_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */ /* Common channel specific registers for omap2 */ -#define OMAP_DMA4_CH_BASE(n) (0x60 * (n) + 0x80) -#define OMAP_DMA4_CCR(n) (0x60 * (n) + 0x80) -#define OMAP_DMA4_CLNK_CTRL(n) (0x60 * (n) + 0x84) -#define OMAP_DMA4_CICR(n) (0x60 * (n) + 0x88) -#define OMAP_DMA4_CSR(n) (0x60 * (n) + 0x8c) -#define OMAP_DMA4_CSDP(n) (0x60 * (n) + 0x90) -#define OMAP_DMA4_CEN(n) (0x60 * (n) + 0x94) -#define OMAP_DMA4_CFN(n) (0x60 * (n) + 0x98) -#define OMAP_DMA4_CSEI(n) (0x60 * (n) + 0xa4) -#define OMAP_DMA4_CSFI(n) (0x60 * (n) + 0xa8) -#define OMAP_DMA4_CDEI(n) (0x60 * (n) + 0xac) -#define OMAP_DMA4_CDFI(n) (0x60 * (n) + 0xb0) -#define OMAP_DMA4_CSAC(n) (0x60 * (n) + 0xb4) -#define OMAP_DMA4_CDAC(n) (0x60 * (n) + 0xb8) +#define OMAP_DMA_CCR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x80) +#define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x84) +#define OMAP_DMA_CICR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x88) +#define OMAP_DMA_CSR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x8c) +#define OMAP_DMA_CSDP_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x90) +#define OMAP_DMA_CEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x94) +#define OMAP_DMA_CFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x98) +#define OMAP_DMA_CSEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa4) +#define OMAP_DMA_CSFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa8) +#define OMAP_DMA_CDEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xac) +#define OMAP_DMA_CDFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb0) +#define OMAP_DMA_CSAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb4) +#define OMAP_DMA_CDAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb8) + +#endif /* Channel specific registers only on omap1 */ -#define OMAP1_DMA_CSSA_L(n) (0x40 * (n) + 0x08) -#define OMAP1_DMA_CSSA_U(n) (0x40 * (n) + 0x0a) -#define OMAP1_DMA_CDSA_L(n) (0x40 * (n) + 0x0c) -#define OMAP1_DMA_CDSA_U(n) (0x40 * (n) + 0x0e) -#define OMAP1_DMA_COLOR_L(n) (0x40 * (n) + 0x20) -#define OMAP1_DMA_COLOR_U(n) (0x40 * (n) + 0x22) -#define OMAP1_DMA_CCR2(n) (0x40 * (n) + 0x24) -#define OMAP1_DMA_LCH_CTRL(n) (0x40 * (n) + 0x2a) /* not on 15xx */ -#define OMAP1_DMA_CCEN(n) 0 -#define OMAP1_DMA_CCFN(n) 0 +#define OMAP1_DMA_CSSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x08) +#define OMAP1_DMA_CSSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0a) +#define OMAP1_DMA_CDSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0c) +#define OMAP1_DMA_CDSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0e) +#define OMAP1_DMA_COLOR_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x20) +#define OMAP1_DMA_CCR2_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x24) +#define OMAP1_DMA_COLOR_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x22) +#define OMAP1_DMA_LCH_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x2a) /* Channel specific registers only on omap2 */ -#define OMAP_DMA4_CSSA(n) (0x60 * (n) + 0x9c) -#define OMAP_DMA4_CDSA(n) (0x60 * (n) + 0xa0) -#define OMAP_DMA4_CCEN(n) (0x60 * (n) + 0xbc) -#define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0) -#define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4) - -/* Dummy defines to keep multi-omap compiles happy */ -#define OMAP1_DMA_REVISION 0 -#define OMAP1_DMA_IRQSTATUS_L0 0 -#define OMAP1_DMA_IRQENABLE_L0 0 -#define OMAP1_DMA_OCP_SYSCONFIG 0 -#define OMAP_DMA4_HW_ID 0 -#define OMAP_DMA4_CAPS_0_L 0 -#define OMAP_DMA4_CAPS_0_U 0 -#define OMAP_DMA4_CAPS_1_L 0 -#define OMAP_DMA4_CAPS_1_U 0 -#define OMAP_DMA4_GSCR 0 -#define OMAP_DMA4_CPC(n) 0 - -#define OMAP_DMA4_LCH_CTRL(n) 0 -#define OMAP_DMA4_COLOR_L(n) 0 -#define OMAP_DMA4_COLOR_U(n) 0 -#define OMAP_DMA4_CCR2(n) 0 -#define OMAP1_DMA_CSSA(n) 0 -#define OMAP1_DMA_CDSA(n) 0 -#define OMAP_DMA4_CSSA_L(n) 0 -#define OMAP_DMA4_CSSA_U(n) 0 -#define OMAP_DMA4_CDSA_L(n) 0 -#define OMAP_DMA4_CDSA_U(n) 0 +#define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x9c) +#define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa0) +#define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xbc) +#define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc0) +#define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc4) /*----------------------------------------------------------------------------*/ @@ -216,98 +196,63 @@ #define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */ #define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */ #define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */ -#define OMAP242X_DMA_VLYNQ_TX 7 /* S_DMA_6 */ -#define OMAP24XX_DMA_EXT_DMAREQ2 7 /* S_DMA_6 */ +#define OMAP24XX_DMA_VLYNQ_TX 7 /* S_DMA_6 */ #define OMAP24XX_DMA_CWT 8 /* S_DMA_7 */ #define OMAP24XX_DMA_AES_TX 9 /* S_DMA_8 */ #define OMAP24XX_DMA_AES_RX 10 /* S_DMA_9 */ #define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */ #define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */ #define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */ -#define OMAP34XX_DMA_SHA2MD5_RX 13 /* S_DMA_12 */ -#define OMAP242X_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */ -#define OMAP242X_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */ -#define OMAP242X_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */ -#define OMAP242X_DMA_EAC_AC_RD 17 /* S_DMA_16 */ -#define OMAP242X_DMA_EAC_AC_WR 18 /* S_DMA_17 */ -#define OMAP242X_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */ -#define OMAP242X_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */ -#define OMAP242X_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */ -#define OMAP242X_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */ -#define OMAP242X_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */ -#define OMAP242X_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */ -#define OMAP242X_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */ -#define OMAP242X_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */ -#define OMAP243X_DMA_EXT_DMAREQ3 14 /* S_DMA_13 */ -#define OMAP24XX_DMA_SPI3_TX0 15 /* S_DMA_14 */ -#define OMAP24XX_DMA_SPI3_RX0 16 /* S_DMA_15 */ -#define OMAP24XX_DMA_MCBSP3_TX 17 /* S_DMA_16 */ -#define OMAP24XX_DMA_MCBSP3_RX 18 /* S_DMA_17 */ -#define OMAP24XX_DMA_MCBSP4_TX 19 /* S_DMA_18 */ -#define OMAP24XX_DMA_MCBSP4_RX 20 /* S_DMA_19 */ -#define OMAP24XX_DMA_MCBSP5_TX 21 /* S_DMA_20 */ -#define OMAP24XX_DMA_MCBSP5_RX 22 /* S_DMA_21 */ -#define OMAP24XX_DMA_SPI3_TX1 23 /* S_DMA_22 */ -#define OMAP24XX_DMA_SPI3_RX1 24 /* S_DMA_23 */ -#define OMAP243X_DMA_EXT_DMAREQ4 25 /* S_DMA_24 */ -#define OMAP243X_DMA_EXT_DMAREQ5 26 /* S_DMA_25 */ -#define OMAP34XX_DMA_I2C3_TX 25 /* S_DMA_24 */ -#define OMAP34XX_DMA_I2C3_RX 26 /* S_DMA_25 */ +#define OMAP24XX_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */ +#define OMAP24XX_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */ +#define OMAP24XX_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */ +#define OMAP24XX_DMA_EAC_AC_RD 17 /* S_DMA_16 */ +#define OMAP24XX_DMA_EAC_AC_WR 18 /* S_DMA_17 */ +#define OMAP24XX_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */ +#define OMAP24XX_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */ +#define OMAP24XX_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */ +#define OMAP24XX_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */ +#define OMAP24XX_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */ +#define OMAP24XX_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */ +#define OMAP24XX_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */ +#define OMAP24XX_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */ #define OMAP24XX_DMA_I2C1_TX 27 /* S_DMA_26 */ #define OMAP24XX_DMA_I2C1_RX 28 /* S_DMA_27 */ #define OMAP24XX_DMA_I2C2_TX 29 /* S_DMA_28 */ #define OMAP24XX_DMA_I2C2_RX 30 /* S_DMA_29 */ -#define OMAP24XX_DMA_MCBSP1_TX 31 /* S_DMA_30 */ -#define OMAP24XX_DMA_MCBSP1_RX 32 /* S_DMA_31 */ -#define OMAP24XX_DMA_MCBSP2_TX 33 /* S_DMA_32 */ -#define OMAP24XX_DMA_MCBSP2_RX 34 /* S_DMA_33 */ -#define OMAP24XX_DMA_SPI1_TX0 35 /* S_DMA_34 */ -#define OMAP24XX_DMA_SPI1_RX0 36 /* S_DMA_35 */ -#define OMAP24XX_DMA_SPI1_TX1 37 /* S_DMA_36 */ -#define OMAP24XX_DMA_SPI1_RX1 38 /* S_DMA_37 */ -#define OMAP24XX_DMA_SPI1_TX2 39 /* S_DMA_38 */ -#define OMAP24XX_DMA_SPI1_RX2 40 /* S_DMA_39 */ -#define OMAP24XX_DMA_SPI1_TX3 41 /* S_DMA_40 */ -#define OMAP24XX_DMA_SPI1_RX3 42 /* S_DMA_41 */ -#define OMAP24XX_DMA_SPI2_TX0 43 /* S_DMA_42 */ -#define OMAP24XX_DMA_SPI2_RX0 44 /* S_DMA_43 */ -#define OMAP24XX_DMA_SPI2_TX1 45 /* S_DMA_44 */ -#define OMAP24XX_DMA_SPI2_RX1 46 /* S_DMA_45 */ -#define OMAP24XX_DMA_MMC2_TX 47 /* S_DMA_46 */ -#define OMAP24XX_DMA_MMC2_RX 48 /* S_DMA_47 */ -#define OMAP24XX_DMA_UART1_TX 49 /* S_DMA_48 */ -#define OMAP24XX_DMA_UART1_RX 50 /* S_DMA_49 */ -#define OMAP24XX_DMA_UART2_TX 51 /* S_DMA_50 */ -#define OMAP24XX_DMA_UART2_RX 52 /* S_DMA_51 */ -#define OMAP24XX_DMA_UART3_TX 53 /* S_DMA_52 */ -#define OMAP24XX_DMA_UART3_RX 54 /* S_DMA_53 */ -#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* S_DMA_54 */ -#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* S_DMA_55 */ -#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* S_DMA_56 */ -#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* S_DMA_57 */ -#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* S_DMA_58 */ -#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* S_DMA_59 */ -#define OMAP24XX_DMA_MMC1_TX 61 /* S_DMA_60 */ -#define OMAP24XX_DMA_MMC1_RX 62 /* S_DMA_61 */ -#define OMAP24XX_DMA_MS 63 /* S_DMA_62 */ -#define OMAP242X_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */ -#define OMAP243X_DMA_EXT_DMAREQ6 64 /* S_DMA_63 */ -#define OMAP34XX_DMA_EXT_DMAREQ3 64 /* S_DMA_63 */ -#define OMAP34XX_DMA_AES2_TX 65 /* S_DMA_64 */ -#define OMAP34XX_DMA_AES2_RX 66 /* S_DMA_65 */ -#define OMAP34XX_DMA_DES2_TX 67 /* S_DMA_66 */ -#define OMAP34XX_DMA_DES2_RX 68 /* S_DMA_67 */ -#define OMAP34XX_DMA_SHA1MD5_RX 69 /* S_DMA_68 */ -#define OMAP34XX_DMA_SPI4_TX0 70 /* S_DMA_69 */ -#define OMAP34XX_DMA_SPI4_RX0 71 /* S_DMA_70 */ -#define OMAP34XX_DSS_DMA0 72 /* S_DMA_71 */ -#define OMAP34XX_DSS_DMA1 73 /* S_DMA_72 */ -#define OMAP34XX_DSS_DMA2 74 /* S_DMA_73 */ -#define OMAP34XX_DSS_DMA3 75 /* S_DMA_74 */ -#define OMAP34XX_DMA_MMC3_TX 77 /* S_DMA_76 */ -#define OMAP34XX_DMA_MMC3_RX 78 /* S_DMA_77 */ -#define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */ -#define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */ +#define OMAP24XX_DMA_MCBSP1_TX 31 /* SDMA_30 */ +#define OMAP24XX_DMA_MCBSP1_RX 32 /* SDMA_31 */ +#define OMAP24XX_DMA_MCBSP2_TX 33 /* SDMA_32 */ +#define OMAP24XX_DMA_MCBSP2_RX 34 /* SDMA_33 */ +#define OMAP24XX_DMA_SPI1_TX0 35 /* SDMA_34 */ +#define OMAP24XX_DMA_SPI1_RX0 36 /* SDMA_35 */ +#define OMAP24XX_DMA_SPI1_TX1 37 /* SDMA_36 */ +#define OMAP24XX_DMA_SPI1_RX1 38 /* SDMA_37 */ +#define OMAP24XX_DMA_SPI1_TX2 39 /* SDMA_38 */ +#define OMAP24XX_DMA_SPI1_RX2 40 /* SDMA_39 */ +#define OMAP24XX_DMA_SPI1_TX3 41 /* SDMA_40 */ +#define OMAP24XX_DMA_SPI1_RX3 42 /* SDMA_41 */ +#define OMAP24XX_DMA_SPI2_TX0 43 /* SDMA_42 */ +#define OMAP24XX_DMA_SPI2_RX0 44 /* SDMA_43 */ +#define OMAP24XX_DMA_SPI2_TX1 45 /* SDMA_44 */ +#define OMAP24XX_DMA_SPI2_RX1 46 /* SDMA_45 */ + +#define OMAP24XX_DMA_UART1_TX 49 /* SDMA_48 */ +#define OMAP24XX_DMA_UART1_RX 50 /* SDMA_49 */ +#define OMAP24XX_DMA_UART2_TX 51 /* SDMA_50 */ +#define OMAP24XX_DMA_UART2_RX 52 /* SDMA_51 */ +#define OMAP24XX_DMA_UART3_TX 53 /* SDMA_52 */ +#define OMAP24XX_DMA_UART3_RX 54 /* SDMA_53 */ +#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* SDMA_54 */ +#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* SDMA_55 */ +#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* SDMA_56 */ +#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* SDMA_57 */ +#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* SDMA_58 */ +#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* SDMA_59 */ +#define OMAP24XX_DMA_MMC1_TX 61 /* SDMA_60 */ +#define OMAP24XX_DMA_MMC1_RX 62 /* SDMA_61 */ +#define OMAP24XX_DMA_MS 63 /* SDMA_62 */ +#define OMAP24XX_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */ /*----------------------------------------------------------------------------*/ @@ -413,11 +358,6 @@ enum omap_dma_burst_mode { OMAP_DMA_DATA_BURST_16, }; -enum end_type { - OMAP_DMA_LITTLE_ENDIAN = 0, - OMAP_DMA_BIG_ENDIAN -}; - enum omap_dma_color_mode { OMAP_DMA_COLOR_DIS = 0, OMAP_DMA_CONSTANT_FILL, @@ -430,34 +370,24 @@ enum omap_dma_write_mode { OMAP_DMA_WRITE_LAST_NON_POSTED }; -enum omap_dma_channel_mode { - OMAP_DMA_LCH_2D = 0, - OMAP_DMA_LCH_G, - OMAP_DMA_LCH_P, - OMAP_DMA_LCH_PD -}; - struct omap_dma_channel_params { int data_type; /* data type 8,16,32 */ int elem_count; /* number of elements in a frame */ int frame_count; /* number of frames in a element */ int src_port; /* Only on OMAP1 REVISIT: Is this needed? */ - int src_amode; /* constant, post increment, indexed, - double indexed */ + int src_amode; /* constant , post increment, indexed , double indexed */ unsigned long src_start; /* source address : physical */ int src_ei; /* source element index */ int src_fi; /* source frame index */ int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */ - int dst_amode; /* constant, post increment, indexed, - double indexed */ + int dst_amode; /* constant , post increment, indexed , double indexed */ unsigned long dst_start; /* source address : physical */ int dst_ei; /* source element index */ int dst_fi; /* source frame index */ - int trigger; /* trigger attached if the channel is - synchronized */ + int trigger; /* trigger attached if the channel is synchronized */ int sync_mode; /* sycn on element, frame , block or packet */ int src_or_dst_synch; /* source synch(1) or destination synch(0) */ @@ -474,8 +404,8 @@ struct omap_dma_channel_params { extern void omap_set_dma_priority(int lch, int dst_port, int priority); extern int omap_request_dma(int dev_id, const char *dev_name, - void (*callback)(int lch, u16 ch_status, void *data), - void *data, int *dma_ch); + void (* callback)(int lch, u16 ch_status, void *data), + void *data, int *dma_ch); extern void omap_enable_dma_irq(int ch, u16 irq_bits); extern void omap_disable_dma_irq(int ch, u16 irq_bits); extern void omap_free_dma(int ch); @@ -488,7 +418,6 @@ extern void omap_set_dma_transfer_params(int lch, int data_type, extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color); extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode); -extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode); extern void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, @@ -507,26 +436,23 @@ extern void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode); extern void omap_set_dma_params(int lch, - struct omap_dma_channel_params *params); + struct omap_dma_channel_params * params); -extern void omap_dma_link_lch(int lch_head, int lch_queue); -extern void omap_dma_unlink_lch(int lch_head, int lch_queue); +extern void omap_dma_link_lch (int lch_head, int lch_queue); +extern void omap_dma_unlink_lch (int lch_head, int lch_queue); extern int omap_set_dma_callback(int lch, - void (*callback)(int lch, u16 ch_status, void *data), + void (* callback)(int lch, u16 ch_status, void *data), void *data); extern dma_addr_t omap_get_dma_src_pos(int lch); extern dma_addr_t omap_get_dma_dst_pos(int lch); +extern int omap_get_dma_src_addr_counter(int lch); extern void omap_clear_dma(int lch); -extern int omap_get_dma_active_status(int lch); extern int omap_dma_running(void); extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams); extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio, unsigned char write_prio); -extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype); -extern void omap_set_dma_src_endian_type(int lch, enum end_type etype); -extern int omap_get_dma_index(int lch, int *ei, int *fi); /* Chaining APIs */ #ifndef CONFIG_ARCH_OMAP1 @@ -552,7 +478,7 @@ extern int omap_dma_chain_status(int chain_id); #endif /* LCD DMA functions */ -extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data), +extern int omap_request_lcd_dma(void (* callback)(u16 status, void *data), void *data); extern void omap_free_lcd_dma(void); extern void omap_setup_lcd_dma(void); diff --git a/trunk/include/asm-arm/arch-omap/dmtimer.h b/trunk/include/asm-arm/arch-omap/dmtimer.h index 02b29e8437ae..fefb276ed402 100644 --- a/trunk/include/asm-arm/arch-omap/dmtimer.h +++ b/trunk/include/asm-arm/arch-omap/dmtimer.h @@ -66,7 +66,6 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer); void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source); void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value); -void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value); void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match); void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger); void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler); diff --git a/trunk/include/asm-arm/arch-omap/fpga.h b/trunk/include/asm-arm/arch-omap/fpga.h index f420881d2a3b..6a883e0bdbb8 100644 --- a/trunk/include/asm-arm/arch-omap/fpga.h +++ b/trunk/include/asm-arm/arch-omap/fpga.h @@ -169,29 +169,30 @@ struct h2p2_dbg_fpga { #define OMAP1510_INT_FPGA (IH_GPIO_BASE + 13) /* IRQ Numbers for interrupts muxed through the FPGA */ -#define OMAP1510_INT_FPGA_ATN (OMAP_FPGA_IRQ_BASE + 0) -#define OMAP1510_INT_FPGA_ACK (OMAP_FPGA_IRQ_BASE + 1) -#define OMAP1510_INT_FPGA2 (OMAP_FPGA_IRQ_BASE + 2) -#define OMAP1510_INT_FPGA3 (OMAP_FPGA_IRQ_BASE + 3) -#define OMAP1510_INT_FPGA4 (OMAP_FPGA_IRQ_BASE + 4) -#define OMAP1510_INT_FPGA5 (OMAP_FPGA_IRQ_BASE + 5) -#define OMAP1510_INT_FPGA6 (OMAP_FPGA_IRQ_BASE + 6) -#define OMAP1510_INT_FPGA7 (OMAP_FPGA_IRQ_BASE + 7) -#define OMAP1510_INT_FPGA8 (OMAP_FPGA_IRQ_BASE + 8) -#define OMAP1510_INT_FPGA9 (OMAP_FPGA_IRQ_BASE + 9) -#define OMAP1510_INT_FPGA10 (OMAP_FPGA_IRQ_BASE + 10) -#define OMAP1510_INT_FPGA11 (OMAP_FPGA_IRQ_BASE + 11) -#define OMAP1510_INT_FPGA12 (OMAP_FPGA_IRQ_BASE + 12) -#define OMAP1510_INT_ETHER (OMAP_FPGA_IRQ_BASE + 13) -#define OMAP1510_INT_FPGAUART1 (OMAP_FPGA_IRQ_BASE + 14) -#define OMAP1510_INT_FPGAUART2 (OMAP_FPGA_IRQ_BASE + 15) -#define OMAP1510_INT_FPGA_TS (OMAP_FPGA_IRQ_BASE + 16) -#define OMAP1510_INT_FPGA17 (OMAP_FPGA_IRQ_BASE + 17) -#define OMAP1510_INT_FPGA_CAM (OMAP_FPGA_IRQ_BASE + 18) -#define OMAP1510_INT_FPGA_RTC_A (OMAP_FPGA_IRQ_BASE + 19) -#define OMAP1510_INT_FPGA_RTC_B (OMAP_FPGA_IRQ_BASE + 20) -#define OMAP1510_INT_FPGA_CD (OMAP_FPGA_IRQ_BASE + 21) -#define OMAP1510_INT_FPGA22 (OMAP_FPGA_IRQ_BASE + 22) -#define OMAP1510_INT_FPGA23 (OMAP_FPGA_IRQ_BASE + 23) +#define OMAP1510_IH_FPGA_BASE IH_BOARD_BASE +#define OMAP1510_INT_FPGA_ATN (OMAP1510_IH_FPGA_BASE + 0) +#define OMAP1510_INT_FPGA_ACK (OMAP1510_IH_FPGA_BASE + 1) +#define OMAP1510_INT_FPGA2 (OMAP1510_IH_FPGA_BASE + 2) +#define OMAP1510_INT_FPGA3 (OMAP1510_IH_FPGA_BASE + 3) +#define OMAP1510_INT_FPGA4 (OMAP1510_IH_FPGA_BASE + 4) +#define OMAP1510_INT_FPGA5 (OMAP1510_IH_FPGA_BASE + 5) +#define OMAP1510_INT_FPGA6 (OMAP1510_IH_FPGA_BASE + 6) +#define OMAP1510_INT_FPGA7 (OMAP1510_IH_FPGA_BASE + 7) +#define OMAP1510_INT_FPGA8 (OMAP1510_IH_FPGA_BASE + 8) +#define OMAP1510_INT_FPGA9 (OMAP1510_IH_FPGA_BASE + 9) +#define OMAP1510_INT_FPGA10 (OMAP1510_IH_FPGA_BASE + 10) +#define OMAP1510_INT_FPGA11 (OMAP1510_IH_FPGA_BASE + 11) +#define OMAP1510_INT_FPGA12 (OMAP1510_IH_FPGA_BASE + 12) +#define OMAP1510_INT_ETHER (OMAP1510_IH_FPGA_BASE + 13) +#define OMAP1510_INT_FPGAUART1 (OMAP1510_IH_FPGA_BASE + 14) +#define OMAP1510_INT_FPGAUART2 (OMAP1510_IH_FPGA_BASE + 15) +#define OMAP1510_INT_FPGA_TS (OMAP1510_IH_FPGA_BASE + 16) +#define OMAP1510_INT_FPGA17 (OMAP1510_IH_FPGA_BASE + 17) +#define OMAP1510_INT_FPGA_CAM (OMAP1510_IH_FPGA_BASE + 18) +#define OMAP1510_INT_FPGA_RTC_A (OMAP1510_IH_FPGA_BASE + 19) +#define OMAP1510_INT_FPGA_RTC_B (OMAP1510_IH_FPGA_BASE + 20) +#define OMAP1510_INT_FPGA_CD (OMAP1510_IH_FPGA_BASE + 21) +#define OMAP1510_INT_FPGA22 (OMAP1510_IH_FPGA_BASE + 22) +#define OMAP1510_INT_FPGA23 (OMAP1510_IH_FPGA_BASE + 23) #endif diff --git a/trunk/include/asm-arm/arch-omap/hardware.h b/trunk/include/asm-arm/arch-omap/hardware.h index 45fdfccbd5d4..91d85b3417b7 100644 --- a/trunk/include/asm-arm/arch-omap/hardware.h +++ b/trunk/include/asm-arm/arch-omap/hardware.h @@ -284,7 +284,6 @@ #include "omap1510.h" #include "omap24xx.h" #include "omap16xx.h" -#include "omap34xx.h" #ifndef __ASSEMBLER__ diff --git a/trunk/include/asm-arm/arch-omap/io.h b/trunk/include/asm-arm/arch-omap/io.h index 0b13557fd30b..160578e1f557 100644 --- a/trunk/include/asm-arm/arch-omap/io.h +++ b/trunk/include/asm-arm/arch-omap/io.h @@ -60,7 +60,6 @@ #define IO_SIZE 0x40000 #define IO_VIRT (IO_PHYS - IO_OFFSET) #define IO_ADDRESS(pa) ((pa) - IO_OFFSET) -#define OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET) #define io_p2v(pa) ((pa) - IO_OFFSET) #define io_v2p(va) ((va) + IO_OFFSET) @@ -92,7 +91,6 @@ #define IO_OFFSET 0x90000000 #define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ -#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ #define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */ #define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */ @@ -150,7 +148,6 @@ #define IO_OFFSET 0x90000000 #define IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ -#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ #define io_p2v(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */ #define io_v2p(va) ((va) - IO_OFFSET)/* Works for L3 and L4 */ @@ -186,12 +183,35 @@ #define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v)) #define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v)) +/* 16 bit uses LDRH/STRH, base +/- offset_8 */ +typedef struct { volatile u16 offset[256]; } __regbase16; +#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \ + ->offset[((vaddr)&0xff)>>1] +#define __REG16(paddr) __REGV16(io_p2v(paddr)) + +/* 8/32 bit uses LDR/STR, base +/- offset_12 */ +typedef struct { volatile u8 offset[4096]; } __regbase8; +#define __REGV8(vaddr) ((__regbase8 *)((vaddr)&~4095)) \ + ->offset[((vaddr)&4095)>>0] +#define __REG8(paddr) __REGV8(io_p2v(paddr)) + +typedef struct { volatile u32 offset[4096]; } __regbase32; +#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \ + ->offset[((vaddr)&4095)>>2] +#define __REG32(paddr) __REGV32(io_p2v(paddr)) + extern void omap1_map_common_io(void); extern void omap1_init_common_hw(void); extern void omap2_map_common_io(void); extern void omap2_init_common_hw(void); +#else + +#define __REG8(paddr) io_p2v(paddr) +#define __REG16(paddr) io_p2v(paddr) +#define __REG32(paddr) io_p2v(paddr) + #endif #endif diff --git a/trunk/include/asm-arm/arch-omap/irqs.h b/trunk/include/asm-arm/arch-omap/irqs.h index 7464c694859b..87973654e625 100644 --- a/trunk/include/asm-arm/arch-omap/irqs.h +++ b/trunk/include/asm-arm/arch-omap/irqs.h @@ -285,41 +285,7 @@ #define OMAP_MAX_GPIO_LINES 192 #define IH_GPIO_BASE (128 + IH2_BASE) #define IH_MPUIO_BASE (OMAP_MAX_GPIO_LINES + IH_GPIO_BASE) -#define OMAP_IRQ_END (IH_MPUIO_BASE + 16) - -/* External FPGA handles interrupts on Innovator boards */ -#define OMAP_FPGA_IRQ_BASE (OMAP_IRQ_END) -#ifdef CONFIG_MACH_OMAP_INNOVATOR -#define OMAP_FPGA_NR_IRQS 24 -#else -#define OMAP_FPGA_NR_IRQS 0 -#endif -#define OMAP_FPGA_IRQ_END (OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS) - -/* External TWL4030 can handle interrupts on 2430 and 34xx boards */ -#define TWL4030_IRQ_BASE (OMAP_FPGA_IRQ_END) -#ifdef CONFIG_TWL4030_CORE -#define TWL4030_BASE_NR_IRQS 8 -#define TWL4030_PWR_NR_IRQS 8 -#else -#define TWL4030_BASE_NR_IRQS 0 -#define TWL4030_PWR_NR_IRQS 0 -#endif -#define TWL4030_IRQ_END (TWL4030_IRQ_BASE + TWL4030_BASE_NR_IRQS) -#define TWL4030_PWR_IRQ_BASE TWL4030_IRQ_END -#define TWL4030_PWR_IRQ_END (TWL4030_PWR_IRQ_BASE + TWL4030_PWR_NR_IRQS) - -/* External TWL4030 gpio interrupts are optional */ -#define TWL4030_GPIO_IRQ_BASE TWL4030_PWR_IRQ_END -#ifdef CONFIG_TWL4030_GPIO -#define TWL4030_GPIO_NR_IRQS 18 -#else -#define TWL4030_GPIO_NR_IRQS 0 -#endif -#define TWL4030_GPIO_IRQ_END (TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS) - -/* Total number of interrupts depends on the enabled blocks above */ -#define NR_IRQS TWL4030_GPIO_IRQ_END +#define IH_BOARD_BASE (16 + IH_MPUIO_BASE) #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) @@ -327,6 +293,14 @@ extern void omap_init_irq(void); #endif +/* + * The definition of NR_IRQS is in board-specific header file, which is + * included via hardware.h + */ #include +#ifndef NR_IRQS +#define NR_IRQS IH_BOARD_BASE +#endif + #endif diff --git a/trunk/include/asm-arm/arch-omap/mcbsp.h b/trunk/include/asm-arm/arch-omap/mcbsp.h index 26c78f67dc8e..c7a0cc1c4e93 100644 --- a/trunk/include/asm-arm/arch-omap/mcbsp.h +++ b/trunk/include/asm-arm/arch-omap/mcbsp.h @@ -24,11 +24,7 @@ #ifndef __ASM_ARCH_OMAP_MCBSP_H #define __ASM_ARCH_OMAP_MCBSP_H -#include -#include - #include -#include #define OMAP730_MCBSP1_BASE 0xfffb1000 #define OMAP730_MCBSP2_BASE 0xfffb1800 @@ -44,9 +40,6 @@ #define OMAP24XX_MCBSP1_BASE 0x48074000 #define OMAP24XX_MCBSP2_BASE 0x48076000 -#define OMAP34XX_MCBSP1_BASE 0x48074000 -#define OMAP34XX_MCBSP2_BASE 0x49022000 - #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) #define OMAP_MCBSP_REG_DRR2 0x00 @@ -81,8 +74,7 @@ #define OMAP_MCBSP_REG_XCERG 0x3A #define OMAP_MCBSP_REG_XCERH 0x3C -#define OMAP_MAX_MCBSP_COUNT 3 -#define MAX_MCBSP_CLOCKS 3 +#define OMAP_MAX_MCBSP_COUNT 3 #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1) #define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1) @@ -125,8 +117,7 @@ #define OMAP_MCBSP_REG_XCERG 0x74 #define OMAP_MCBSP_REG_XCERH 0x78 -#define OMAP_MAX_MCBSP_COUNT 2 -#define MAX_MCBSP_CLOCKS 2 +#define OMAP_MAX_MCBSP_COUNT 2 #define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1) #define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1) @@ -307,55 +298,6 @@ struct omap_mcbsp_spi_cfg { omap_mcbsp_word_length word_length; }; -/* Platform specific configuration */ -struct omap_mcbsp_ops { - void (*request)(unsigned int); - void (*free)(unsigned int); - int (*check)(unsigned int); -}; - -struct omap_mcbsp_platform_data { - u32 virt_base; - u8 dma_rx_sync, dma_tx_sync; - u16 rx_irq, tx_irq; - struct omap_mcbsp_ops *ops; - char const *clk_name; -}; - -struct omap_mcbsp { - struct device *dev; - u32 io_base; - u8 id; - u8 free; - omap_mcbsp_word_length rx_word_length; - omap_mcbsp_word_length tx_word_length; - - omap_mcbsp_io_type_t io_type; /* IRQ or poll */ - /* IRQ based TX/RX */ - int rx_irq; - int tx_irq; - - /* DMA stuff */ - u8 dma_rx_sync; - short dma_rx_lch; - u8 dma_tx_sync; - short dma_tx_lch; - - /* Completion queues */ - struct completion tx_irq_completion; - struct completion rx_irq_completion; - struct completion tx_dma_completion; - struct completion rx_dma_completion; - - /* Protect the field .free, while checking if the mcbsp is in use */ - spinlock_t lock; - struct omap_mcbsp_platform_data *pdata; - struct clk *clk; -}; - -int omap_mcbsp_init(void); -void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, - int size); void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); int omap_mcbsp_request(unsigned int id); void omap_mcbsp_free(unsigned int id); diff --git a/trunk/include/asm-arm/arch-omap/omap34xx.h b/trunk/include/asm-arm/arch-omap/omap34xx.h deleted file mode 100644 index aa30c6d10abd..000000000000 --- a/trunk/include/asm-arm/arch-omap/omap34xx.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * include/asm-arm/arch-omap/omap34xx.h - * - * This file contains the processor specific definitions of the TI OMAP34XX. - * - * Copyright (C) 2007 Texas Instruments. - * Copyright (C) 2007 Nokia 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 __ASM_ARCH_OMAP34XX_H -#define __ASM_ARCH_OMAP34XX_H - -/* - * Please place only base defines here and put the rest in device - * specific headers. - */ - -#define L4_34XX_BASE 0x48000000 -#define L4_WK_34XX_BASE 0x48300000 -#define L4_WK_OMAP_BASE L4_WK_34XX_BASE -#define L4_PER_34XX_BASE 0x49000000 -#define L4_PER_OMAP_BASE L4_PER_34XX_BASE -#define L4_EMU_34XX_BASE 0x54000000 -#define L4_EMU_BASE L4_EMU_34XX_BASE -#define L3_34XX_BASE 0x68000000 -#define L3_OMAP_BASE L3_34XX_BASE - -#define OMAP3430_32KSYNCT_BASE 0x48320000 -#define OMAP3430_CM_BASE 0x48004800 -#define OMAP3430_PRM_BASE 0x48306800 -#define OMAP343X_SMS_BASE 0x6C000000 -#define OMAP343X_SDRC_BASE 0x6D000000 -#define OMAP34XX_GPMC_BASE 0x6E000000 -#define OMAP343X_SCM_BASE 0x48002000 -#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE - -#define OMAP34XX_IC_BASE 0x48200000 -#define OMAP34XX_IVA_INTC_BASE 0x40000000 -#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000) -#define OMAP34XX_HSUSB_HOST_BASE (L4_34XX_BASE + 0x64000) -#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000) - - -#if defined(CONFIG_ARCH_OMAP3430) - -#define OMAP2_32KSYNCT_BASE OMAP3430_32KSYNCT_BASE -#define OMAP2_CM_BASE OMAP3430_CM_BASE -#define OMAP2_PRM_BASE OMAP3430_PRM_BASE -#define OMAP2_VA_IC_BASE IO_ADDRESS(OMAP34XX_IC_BASE) - -#endif - -#define OMAP34XX_DSP_BASE 0x58000000 -#define OMAP34XX_DSP_MEM_BASE (OMAP34XX_DSP_BASE + 0x0) -#define OMAP34XX_DSP_IPI_BASE (OMAP34XX_DSP_BASE + 0x1000000) -#define OMAP34XX_DSP_MMU_BASE (OMAP34XX_DSP_BASE + 0x2000000) -#endif /* __ASM_ARCH_OMAP34XX_H */ - diff --git a/trunk/include/asm-arm/arch-omap/sram.h b/trunk/include/asm-arm/arch-omap/sram.h index be59f4a9828b..bb9bb3fd532f 100644 --- a/trunk/include/asm-arm/arch-omap/sram.h +++ b/trunk/include/asm-arm/arch-omap/sram.h @@ -11,7 +11,6 @@ #ifndef __ARCH_ARM_OMAP_SRAM_H #define __ARCH_ARM_OMAP_SRAM_H -extern int __init omap_sram_init(void); extern void * omap_sram_push(void * start, unsigned long size); extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); @@ -22,35 +21,17 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); /* Do not use these */ -extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); -extern unsigned long omap1_sram_reprogram_clock_sz; +extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl); +extern unsigned long sram_reprogram_clock_sz; -extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl); -extern unsigned long omap24xx_sram_reprogram_clock_sz; +extern void sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, + u32 base_cs, u32 force_unlock); +extern unsigned long sram_ddr_init_sz; -extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, - u32 base_cs, u32 force_unlock); -extern unsigned long omap242x_sram_ddr_init_sz; +extern u32 sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); +extern unsigned long sram_set_prcm_sz; -extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, - int bypass); -extern unsigned long omap242x_sram_set_prcm_sz; - -extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, - u32 mem_type); -extern unsigned long omap242x_sram_reprogram_sdrc_sz; - - -extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, - u32 base_cs, u32 force_unlock); -extern unsigned long omap243x_sram_ddr_init_sz; - -extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, - int bypass); -extern unsigned long omap243x_sram_set_prcm_sz; - -extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, - u32 mem_type); -extern unsigned long omap243x_sram_reprogram_sdrc_sz; +extern void sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type); +extern unsigned long sram_reprogram_sdrc_sz; #endif diff --git a/trunk/include/asm-arm/arch-omap/tc.h b/trunk/include/asm-arm/arch-omap/tc.h index 65a9c82d3bf7..8ded218cbea5 100644 --- a/trunk/include/asm-arm/arch-omap/tc.h +++ b/trunk/include/asm-arm/arch-omap/tc.h @@ -75,14 +75,16 @@ #ifndef __ASSEMBLER__ /* EMIF Slow Interface Configuration Register */ +#define OMAP_EMIFS_CONFIG_REG __REG32(EMIFS_CONFIG) + #define OMAP_EMIFS_CONFIG_FR (1 << 4) #define OMAP_EMIFS_CONFIG_PDE (1 << 3) #define OMAP_EMIFS_CONFIG_PWD_EN (1 << 2) #define OMAP_EMIFS_CONFIG_BM (1 << 1) #define OMAP_EMIFS_CONFIG_WP (1 << 0) -#define EMIFS_CCS(n) (EMIFS_CS0_CONFIG + (4 * (n))) -#define EMIFS_ACS(n) (EMIFS_ACS0 + (4 * (n))) +#define EMIFS_CCS(n) __REG32(EMIFS_CS0_CONFIG + (4 * (n))) +#define EMIFS_ACS(n) __REG32(EMIFS_ACS0 + (4 * (n))) /* Almost all documentation for chip and board memory maps assumes * BM is clear. Most devel boards have a switch to control booting @@ -91,13 +93,13 @@ */ static inline u32 omap_cs0_phys(void) { - return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) + return (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM) ? OMAP_CS3_PHYS : 0; } static inline u32 omap_cs3_phys(void) { - return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM) + return (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM) ? 0 : OMAP_CS3_PHYS; } diff --git a/trunk/include/asm-arm/arch-omap/usb.h b/trunk/include/asm-arm/arch-omap/usb.h index ddf1861e6df9..2147d18aaeae 100644 --- a/trunk/include/asm-arm/arch-omap/usb.h +++ b/trunk/include/asm-arm/arch-omap/usb.h @@ -34,8 +34,11 @@ /* * OTG and transceiver registers, for OMAPs starting with ARM926 */ -#define OTG_REV (OTG_BASE + 0x00) -#define OTG_SYSCON_1 (OTG_BASE + 0x04) +#define OTG_REG32(offset) __REG32(OTG_BASE + (offset)) +#define OTG_REG16(offset) __REG16(OTG_BASE + (offset)) + +#define OTG_REV_REG OTG_REG32(0x00) +#define OTG_SYSCON_1_REG OTG_REG32(0x04) # define USB2_TRX_MODE(w) (((w)>>24)&0x07) # define USB1_TRX_MODE(w) (((w)>>20)&0x07) # define USB0_TRX_MODE(w) (((w)>>16)&0x07) @@ -44,7 +47,7 @@ # define DEV_IDLE_EN (1 << 13) # define OTG_RESET_DONE (1 << 2) # define OTG_SOFT_RESET (1 << 1) -#define OTG_SYSCON_2 (OTG_BASE + 0x08) +#define OTG_SYSCON_2_REG OTG_REG32(0x08) # define OTG_EN (1 << 31) # define USBX_SYNCHRO (1 << 30) # define OTG_MST16 (1 << 29) @@ -62,7 +65,7 @@ # define HMC_TLLSPEED (1 << 7) # define HMC_TLLATTACH (1 << 6) # define OTG_HMC(w) (((w)>>0)&0x3f) -#define OTG_CTRL (OTG_BASE + 0x0c) +#define OTG_CTRL_REG OTG_REG32(0x0c) # define OTG_USB2_EN (1 << 29) # define OTG_USB2_DP (1 << 28) # define OTG_USB2_DM (1 << 27) @@ -89,7 +92,7 @@ # define OTG_PD_VBUS (1 << 2) # define OTG_PU_VBUS (1 << 1) # define OTG_PU_ID (1 << 0) -#define OTG_IRQ_EN (OTG_BASE + 0x10) /* 16-bit */ +#define OTG_IRQ_EN_REG OTG_REG16(0x10) # define DRIVER_SWITCH (1 << 15) # define A_VBUS_ERR (1 << 13) # define A_REQ_TMROUT (1 << 12) @@ -99,9 +102,9 @@ # define B_SRP_DONE (1 << 8) # define B_SRP_STARTED (1 << 7) # define OPRT_CHG (1 << 0) -#define OTG_IRQ_SRC (OTG_BASE + 0x14) /* 16-bit */ +#define OTG_IRQ_SRC_REG OTG_REG16(0x14) // same bits as in IRQ_EN -#define OTG_OUTCTRL (OTG_BASE + 0x18) /* 16-bit */ +#define OTG_OUTCTRL_REG OTG_REG16(0x18) # define OTGVPD (1 << 14) # define OTGVPU (1 << 13) # define OTGPUID (1 << 12) @@ -114,13 +117,13 @@ # define USB0VDR (1 << 2) # define USB0PDEN (1 << 1) # define USB0PUEN (1 << 0) -#define OTG_TEST (OTG_BASE + 0x20) /* 16-bit */ -#define OTG_VENDOR_CODE (OTG_BASE + 0xfc) /* 16-bit */ +#define OTG_TEST_REG OTG_REG16(0x20) +#define OTG_VENDOR_CODE_REG OTG_REG32(0xfc) /*-------------------------------------------------------------------------*/ /* OMAP1 */ -#define USB_TRANSCEIVER_CTRL (0xfffe1000 + 0x0064) +#define USB_TRANSCEIVER_CTRL_REG __REG32(0xfffe1000 + 0x0064) # define CONF_USB2_UNI_R (1 << 8) # define CONF_USB1_UNI_R (1 << 7) # define CONF_USB_PORT0_R(x) (((x)>>4)&0x7) diff --git a/trunk/include/asm-generic/Kbuild.asm b/trunk/include/asm-generic/Kbuild.asm index 7cd25b8e7c9a..92a6d91d0c1a 100644 --- a/trunk/include/asm-generic/Kbuild.asm +++ b/trunk/include/asm-generic/Kbuild.asm @@ -1,6 +1,6 @@ header-y += kvm.h -ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),) +ifeq ($(wildcard include/asm-$(SRCARCH)/a.out.h),include/asm-$(SRCARCH)/a.out.h) unifdef-y += a.out.h endif unifdef-y += auxvec.h diff --git a/trunk/include/asm-powerpc/Kbuild b/trunk/include/asm-powerpc/Kbuild index bca352e033c3..7381916dfcbb 100644 --- a/trunk/include/asm-powerpc/Kbuild +++ b/trunk/include/asm-powerpc/Kbuild @@ -1,5 +1,6 @@ include include/asm-generic/Kbuild.asm +header-y += a.out.h header-y += auxvec.h header-y += ioctls.h header-y += mman.h diff --git a/trunk/include/asm-x86/kvm_host.h b/trunk/include/asm-x86/kvm_host.h index 844f2a89afbc..1d8cd01fa514 100644 --- a/trunk/include/asm-x86/kvm_host.h +++ b/trunk/include/asm-x86/kvm_host.h @@ -18,7 +18,6 @@ #include #include -#include #include #define KVM_MAX_VCPUS 16 @@ -283,8 +282,7 @@ struct kvm_vcpu_arch { struct x86_emulate_ctxt emulate_ctxt; gpa_t time; - struct pvclock_vcpu_time_info hv_clock; - unsigned int hv_clock_tsc_khz; + struct kvm_vcpu_time_info hv_clock; unsigned int time_offset; struct page *time_page; }; diff --git a/trunk/include/asm-x86/kvm_para.h b/trunk/include/asm-x86/kvm_para.h index bfd9900742bf..509845942070 100644 --- a/trunk/include/asm-x86/kvm_para.h +++ b/trunk/include/asm-x86/kvm_para.h @@ -48,6 +48,24 @@ struct kvm_mmu_op_release_pt { #ifdef __KERNEL__ #include +/* xen binary-compatible interface. See xen headers for details */ +struct kvm_vcpu_time_info { + uint32_t version; + uint32_t pad0; + uint64_t tsc_timestamp; + uint64_t system_time; + uint32_t tsc_to_system_mul; + int8_t tsc_shift; + int8_t pad[3]; +} __attribute__((__packed__)); /* 32 bytes */ + +struct kvm_wall_clock { + uint32_t wc_version; + uint32_t wc_sec; + uint32_t wc_nsec; +} __attribute__((__packed__)); + + extern void kvmclock_init(void); diff --git a/trunk/include/asm-x86/msr.h b/trunk/include/asm-x86/msr.h index 2b5f2c91db25..3707650a169b 100644 --- a/trunk/include/asm-x86/msr.h +++ b/trunk/include/asm-x86/msr.h @@ -18,7 +18,7 @@ static inline unsigned long long native_read_tscp(unsigned int *aux) unsigned long low, high; asm volatile(".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (*aux)); - return low | ((u64)high << 32); + return low | ((u64)high >> 32); } /* diff --git a/trunk/include/asm-x86/pvclock-abi.h b/trunk/include/asm-x86/pvclock-abi.h deleted file mode 100644 index 6857f840b243..000000000000 --- a/trunk/include/asm-x86/pvclock-abi.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _ASM_X86_PVCLOCK_ABI_H_ -#define _ASM_X86_PVCLOCK_ABI_H_ -#ifndef __ASSEMBLY__ - -/* - * These structs MUST NOT be changed. - * They are the ABI between hypervisor and guest OS. - * Both Xen and KVM are using this. - * - * pvclock_vcpu_time_info holds the system time and the tsc timestamp - * of the last update. So the guest can use the tsc delta to get a - * more precise system time. There is one per virtual cpu. - * - * pvclock_wall_clock references the point in time when the system - * time was zero (usually boot time), thus the guest calculates the - * current wall clock by adding the system time. - * - * Protocol for the "version" fields is: hypervisor raises it (making - * it uneven) before it starts updating the fields and raises it again - * (making it even) when it is done. Thus the guest can make sure the - * time values it got are consistent by checking the version before - * and after reading them. - */ - -struct pvclock_vcpu_time_info { - u32 version; - u32 pad0; - u64 tsc_timestamp; - u64 system_time; - u32 tsc_to_system_mul; - s8 tsc_shift; - u8 pad[3]; -} __attribute__((__packed__)); /* 32 bytes */ - -struct pvclock_wall_clock { - u32 version; - u32 sec; - u32 nsec; -} __attribute__((__packed__)); - -#endif /* __ASSEMBLY__ */ -#endif /* _ASM_X86_PVCLOCK_ABI_H_ */ diff --git a/trunk/include/asm-x86/pvclock.h b/trunk/include/asm-x86/pvclock.h deleted file mode 100644 index 85b1bba8e0a3..000000000000 --- a/trunk/include/asm-x86/pvclock.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _ASM_X86_PVCLOCK_H_ -#define _ASM_X86_PVCLOCK_H_ - -#include -#include - -/* some helper functions for xen and kvm pv clock sources */ -cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src); -void pvclock_read_wallclock(struct pvclock_wall_clock *wall, - struct pvclock_vcpu_time_info *vcpu, - struct timespec *ts); - -#endif /* _ASM_X86_PVCLOCK_H_ */ diff --git a/trunk/include/asm-x86/xen/page.h b/trunk/include/asm-x86/xen/page.h index e11f24038b1d..baf3a4dce28c 100644 --- a/trunk/include/asm-x86/xen/page.h +++ b/trunk/include/asm-x86/xen/page.h @@ -150,9 +150,13 @@ static inline pte_t __pte_ma(pteval_t x) return (pte_t) { .pte = x }; } +#ifdef CONFIG_X86_PAE #define pmd_val_ma(v) ((v).pmd) #define pud_val_ma(v) ((v).pgd.pgd) #define __pmd_ma(x) ((pmd_t) { (x) } ) +#else /* !X86_PAE */ +#define pmd_val_ma(v) ((v).pud.pgd.pgd) +#endif /* CONFIG_X86_PAE */ #define pgd_val_ma(x) ((x).pgd) diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index 71d70d1fbce2..b6fbb2573e88 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -166,7 +166,7 @@ unifdef-y += acct.h unifdef-y += adb.h unifdef-y += adfs_fs.h unifdef-y += agpgart.h -ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),) +ifeq ($(wildcard include/asm-$(SRCARCH)/a.out.h),include/asm-$(SRCARCH)/a.out.h) unifdef-y += a.out.h endif unifdef-y += apm_bios.h diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 8b82974bdc12..63c3bb98558f 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -571,7 +571,7 @@ extern void audit_log_lost(const char *message); extern int audit_update_lsm_rules(void); /* Private API (for audit.c only) */ -extern int audit_filter_user(struct netlink_skb_parms *cb); +extern int audit_filter_user(struct netlink_skb_parms *cb, int type); extern int audit_filter_type(int type); extern int audit_receive_filter(int type, int pid, int uid, int seq, void *data, size_t datasz, uid_t loginuid, diff --git a/trunk/include/linux/bootmem.h b/trunk/include/linux/bootmem.h index 686895bacd9d..6a5dbdc8a7dc 100644 --- a/trunk/include/linux/bootmem.h +++ b/trunk/include/linux/bootmem.h @@ -94,7 +94,7 @@ extern unsigned long init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn); -extern int reserve_bootmem_node(pg_data_t *pgdat, +extern void reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, unsigned long size, int flags); diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index d982eb89c77d..2a6639407c80 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -300,7 +300,7 @@ extern int d_validate(struct dentry *, struct dentry *); extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); extern char *__d_path(const struct path *path, struct path *root, char *, int); -extern char *d_path(const struct path *, char *, int); +extern char *d_path(struct path *, char *, int); extern char *dentry_path(struct dentry *, char *, int); /* Allocation counts.. */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index d8e2762ed14d..d490779f18d9 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -83,7 +83,6 @@ extern int dir_notify_enable; #define READ_SYNC (READ | (1 << BIO_RW_SYNC)) #define READ_META (READ | (1 << BIO_RW_META)) #define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC)) -#define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC)) #define WRITE_BARRIER ((1 << BIO_RW) | (1 << BIO_RW_BARRIER)) #define SEL_IN 1 @@ -895,6 +894,8 @@ static inline int file_check_writeable(struct file *filp) typedef struct files_struct *fl_owner_t; struct file_lock_operations { + void (*fl_insert)(struct file_lock *); /* lock insertion callback */ + void (*fl_remove)(struct file_lock *); /* lock removal callback */ void (*fl_copy_lock)(struct file_lock *, struct file_lock *); void (*fl_release_private)(struct file_lock *); }; diff --git a/trunk/include/linux/i2c.h b/trunk/include/linux/i2c.h index 8dc730132192..fb9af6a0fe9c 100644 --- a/trunk/include/linux/i2c.h +++ b/trunk/include/linux/i2c.h @@ -171,7 +171,7 @@ struct i2c_client { struct i2c_adapter *adapter; /* the adapter we sit on */ struct i2c_driver *driver; /* and our access routines */ struct device dev; /* the device structure */ - int irq; /* irq issued by device */ + int irq; /* irq issued by device (or -1) */ struct list_head list; /* DEPRECATED */ struct completion released; }; diff --git a/trunk/include/linux/inet_lro.h b/trunk/include/linux/inet_lro.h index c4335faebb63..80335b7d77c5 100644 --- a/trunk/include/linux/inet_lro.h +++ b/trunk/include/linux/inet_lro.h @@ -84,11 +84,7 @@ struct net_lro_mgr { from received packets and eth protocol is still ETH_P_8021Q */ - /* - * Set for generated SKBs that are not added to - * the frag list in fragmented mode - */ - u32 ip_summed; + u32 ip_summed; /* Set in non generated SKBs in page mode */ u32 ip_summed_aggr; /* Set in aggregated SKBs: CHECKSUM_UNNECESSARY * or CHECKSUM_NONE */ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index d150c57e5f0a..e075c4b762fb 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -534,8 +534,8 @@ struct input_absinfo { #define KEY_FRAMEBACK 0x1b4 /* Consumer - transport controls */ #define KEY_FRAMEFORWARD 0x1b5 + #define KEY_CONTEXT_MENU 0x1b6 /* GenDesc - system context menu */ -#define KEY_MEDIA_REPEAT 0x1b7 /* Consumer - transport control */ #define KEY_DEL_EOL 0x1c0 #define KEY_DEL_EOS 0x1c1 diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index de9d1df4bba2..092b1b25291d 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -33,7 +33,6 @@ #define KVM_REQ_REPORT_TPR_ACCESS 2 #define KVM_REQ_MMU_RELOAD 3 #define KVM_REQ_TRIPLE_FAULT 4 -#define KVM_REQ_PENDING_TIMER 5 struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 25f87102ab66..f27fd2009334 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -88,8 +88,6 @@ struct wireless_dev; #define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ #define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ -#ifdef __KERNEL__ - /* * Compute the worst case header length according to the protocols * used. @@ -116,8 +114,6 @@ struct wireless_dev; #define MAX_HEADER (LL_MAX_HEADER + 48) #endif -#endif /* __KERNEL__ */ - struct net_device_subqueue { /* Give a control state for each queue. This struct may contain diff --git a/trunk/include/linux/thermal.h b/trunk/include/linux/thermal.h index 917707e6151d..06d3e6eb9ca8 100644 --- a/trunk/include/linux/thermal.h +++ b/trunk/include/linux/thermal.h @@ -66,7 +66,8 @@ struct thermal_cooling_device { ((long)t-2732+5)/10 : ((long)t-2732-5)/10) #define CELSIUS_TO_KELVIN(t) ((t)*10+2732) -#if defined(CONFIG_THERMAL_HWMON) +#if defined(CONFIG_HWMON) || \ + (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE)) /* thermal zone devices with the same type share one hwmon device */ struct thermal_hwmon_device { char type[THERMAL_NAME_LENGTH]; @@ -93,7 +94,8 @@ struct thermal_zone_device { struct idr idr; struct mutex lock; /* protect cooling devices list */ struct list_head node; -#if defined(CONFIG_THERMAL_HWMON) +#if defined(CONFIG_HWMON) || \ + (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE)) struct list_head hwmon_node; struct thermal_hwmon_device *hwmon; struct thermal_hwmon_attr temp_input; /* hwmon sys attr */ diff --git a/trunk/include/linux/tty_driver.h b/trunk/include/linux/tty_driver.h index d2a003586761..59f1c0bd8f9c 100644 --- a/trunk/include/linux/tty_driver.h +++ b/trunk/include/linux/tty_driver.h @@ -27,7 +27,8 @@ * This routine is called by the kernel to write a series of * characters to the tty device. The characters may come from * user space or kernel space. This routine will return the - * number of characters actually accepted for writing. + * number of characters actually accepted for writing. This + * routine is mandatory. * * Optional: Required for writable devices. * @@ -133,7 +134,7 @@ * This routine notifies the tty driver that it should hangup the * tty device. * - * Optional: + * Required: * * void (*break_ctl)(struct tty_stuct *tty, int state); * diff --git a/trunk/include/media/cx25840.h b/trunk/include/media/cx25840.h index db431d513f2f..cd599ad29fb2 100644 --- a/trunk/include/media/cx25840.h +++ b/trunk/include/media/cx25840.h @@ -32,16 +32,12 @@ enum cx25840_video_input { CX25840_COMPOSITE7, CX25840_COMPOSITE8, - /* S-Video inputs consist of one luma input (In1-In8) ORed with one + /* S-Video inputs consist of one luma input (In1-In4) ORed with one chroma input (In5-In8) */ CX25840_SVIDEO_LUMA1 = 0x10, CX25840_SVIDEO_LUMA2 = 0x20, CX25840_SVIDEO_LUMA3 = 0x30, CX25840_SVIDEO_LUMA4 = 0x40, - CX25840_SVIDEO_LUMA5 = 0x50, - CX25840_SVIDEO_LUMA6 = 0x60, - CX25840_SVIDEO_LUMA7 = 0x70, - CX25840_SVIDEO_LUMA8 = 0x80, CX25840_SVIDEO_CHROMA4 = 0x400, CX25840_SVIDEO_CHROMA5 = 0x500, CX25840_SVIDEO_CHROMA6 = 0x600, diff --git a/trunk/include/media/ir-common.h b/trunk/include/media/ir-common.h index b8e8aa91905a..bfee8be5d63f 100644 --- a/trunk/include/media/ir-common.h +++ b/trunk/include/media/ir-common.h @@ -146,7 +146,6 @@ extern IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE]; -extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE]; #endif diff --git a/trunk/include/media/v4l2-dev.h b/trunk/include/media/v4l2-dev.h index 859f7a6f6f67..33f01ae08f76 100644 --- a/trunk/include/media/v4l2-dev.h +++ b/trunk/include/media/v4l2-dev.h @@ -40,9 +40,9 @@ #define VFL_TYPE_VTX 3 /* Video standard functions */ -extern const char *v4l2_norm_to_name(v4l2_std_id id); +extern char *v4l2_norm_to_name(v4l2_std_id id); extern int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, const char *name); + int id, char *name); /* Prints the ioctl in a human-readable format */ extern void v4l_printk_ioctl(unsigned int cmd); diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index f422f7218e1c..e0a612bc9c4e 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -367,12 +367,6 @@ static inline int ipv6_addr_any(const struct in6_addr *a) a->s6_addr32[2] | a->s6_addr32[3] ) == 0); } -static inline int ipv6_addr_loopback(const struct in6_addr *a) -{ - return ((a->s6_addr32[0] | a->s6_addr32[1] | - a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0); -} - static inline int ipv6_addr_v4mapped(const struct in6_addr *a) { return ((a->s6_addr32[0] | a->s6_addr32[1] | diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index bcd1623245cb..dae3f9ec1154 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -595,15 +595,6 @@ enum ieee80211_key_alg { ALG_CCMP, }; -/** - * enum ieee80211_key_len - key length - * @WEP40: WEP 5 byte long key - * @WEP104: WEP 13 byte long key - */ -enum ieee80211_key_len { - LEN_WEP40 = 5, - LEN_WEP104 = 13, -}; /** * enum ieee80211_key_flags - key flags diff --git a/trunk/include/net/net_namespace.h b/trunk/include/net/net_namespace.h index d9dd0f707296..aa540e6be502 100644 --- a/trunk/include/net/net_namespace.h +++ b/trunk/include/net/net_namespace.h @@ -95,11 +95,6 @@ extern struct list_head net_namespace_list; #ifdef CONFIG_NET_NS extern void __put_net(struct net *net); -static inline int net_alive(struct net *net) -{ - return net && atomic_read(&net->count); -} - static inline struct net *get_net(struct net *net) { atomic_inc(&net->count); @@ -130,12 +125,6 @@ int net_eq(const struct net *net1, const struct net *net2) return net1 == net2; } #else - -static inline int net_alive(struct net *net) -{ - return 1; -} - static inline struct net *get_net(struct net *net) { return net; diff --git a/trunk/include/net/sch_generic.h b/trunk/include/net/sch_generic.h index a87fc0312edc..ab502ec1c61c 100644 --- a/trunk/include/net/sch_generic.h +++ b/trunk/include/net/sch_generic.h @@ -178,7 +178,7 @@ extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, u32 parentid); extern void tcf_destroy(struct tcf_proto *tp); -extern void tcf_destroy_chain(struct tcf_proto **fl); +extern void tcf_destroy_chain(struct tcf_proto *fl); static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff_head *list) diff --git a/trunk/include/xen/interface/xen.h b/trunk/include/xen/interface/xen.h index 819a0331cda9..9b018da48cf3 100644 --- a/trunk/include/xen/interface/xen.h +++ b/trunk/include/xen/interface/xen.h @@ -10,7 +10,6 @@ #define __XEN_PUBLIC_XEN_H__ #include -#include /* * XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS). @@ -337,7 +336,7 @@ struct vcpu_info { uint8_t evtchn_upcall_mask; unsigned long evtchn_pending_sel; struct arch_vcpu_info arch; - struct pvclock_vcpu_time_info time; + struct vcpu_time_info time; }; /* 64 bytes (x86) */ /* @@ -385,7 +384,9 @@ struct shared_info { * Wallclock time: updated only by control software. Guests should base * their gettimeofday() syscall on this wallclock-base value. */ - struct pvclock_wall_clock wc; + uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */ + uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */ + uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */ struct arch_shared_info arch; diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index e092f1c0ce30..e8692a5748c2 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -738,7 +738,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (!audit_enabled && msg_type != AUDIT_USER_AVC) return 0; - err = audit_filter_user(&NETLINK_CB(skb)); + err = audit_filter_user(&NETLINK_CB(skb), msg_type); if (err == 1) { err = 0; if (msg_type == AUDIT_USER_TTY) { @@ -779,7 +779,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } /* fallthrough */ case AUDIT_LIST: - err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid, + err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, uid, seq, data, nlmsg_len(nlh), loginuid, sessionid, sid); break; @@ -798,7 +798,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } /* fallthrough */ case AUDIT_LIST_RULES: - err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid, + err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, uid, seq, data, nlmsg_len(nlh), loginuid, sessionid, sid); break; diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index 98c50cc671bb..0e0bd27e6512 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -1544,7 +1544,6 @@ static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid, * @data: payload data * @datasz: size of payload data * @loginuid: loginuid of sender - * @sessionid: sessionid for netlink audit message * @sid: SE Linux Security ID of sender */ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, @@ -1721,7 +1720,7 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb, return 1; } -int audit_filter_user(struct netlink_skb_parms *cb) +int audit_filter_user(struct netlink_skb_parms *cb, int type) { enum audit_state state = AUDIT_DISABLED; struct audit_entry *e; diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 7d1136e97c14..449def8074fe 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -1096,64 +1096,21 @@ static void unqueue_me_pi(struct futex_q *q) * private futexes. */ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, - struct task_struct *newowner, - struct rw_semaphore *fshared) + struct task_struct *newowner) { u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS; struct futex_pi_state *pi_state = q->pi_state; - struct task_struct *oldowner = pi_state->owner; u32 uval, curval, newval; - int ret, attempt = 0; + int ret; /* Owner died? */ - if (!pi_state->owner) - newtid |= FUTEX_OWNER_DIED; - - /* - * We are here either because we stole the rtmutex from the - * pending owner or we are the pending owner which failed to - * get the rtmutex. We have to replace the pending owner TID - * in the user space variable. This must be atomic as we have - * to preserve the owner died bit here. - * - * Note: We write the user space value _before_ changing the - * pi_state because we can fault here. Imagine swapped out - * pages or a fork, which was running right before we acquired - * mmap_sem, that marked all the anonymous memory readonly for - * cow. - * - * Modifying pi_state _before_ the user space value would - * leave the pi_state in an inconsistent state when we fault - * here, because we need to drop the hash bucket lock to - * handle the fault. This might be observed in the PID check - * in lookup_pi_state. - */ -retry: - if (get_futex_value_locked(&uval, uaddr)) - goto handle_fault; - - while (1) { - newval = (uval & FUTEX_OWNER_DIED) | newtid; - - curval = cmpxchg_futex_value_locked(uaddr, uval, newval); - - if (curval == -EFAULT) - goto handle_fault; - if (curval == uval) - break; - uval = curval; - } - - /* - * We fixed up user space. Now we need to fix the pi_state - * itself. - */ if (pi_state->owner != NULL) { spin_lock_irq(&pi_state->owner->pi_lock); WARN_ON(list_empty(&pi_state->list)); list_del_init(&pi_state->list); spin_unlock_irq(&pi_state->owner->pi_lock); - } + } else + newtid |= FUTEX_OWNER_DIED; pi_state->owner = newowner; @@ -1161,35 +1118,26 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, WARN_ON(!list_empty(&pi_state->list)); list_add(&pi_state->list, &newowner->pi_state_list); spin_unlock_irq(&newowner->pi_lock); - return 0; /* - * To handle the page fault we need to drop the hash bucket - * lock here. That gives the other task (either the pending - * owner itself or the task which stole the rtmutex) the - * chance to try the fixup of the pi_state. So once we are - * back from handling the fault we need to check the pi_state - * after reacquiring the hash bucket lock and before trying to - * do another fixup. When the fixup has been done already we - * simply return. + * We own it, so we have to replace the pending owner + * TID. This must be atomic as we have preserve the + * owner died bit here. */ -handle_fault: - spin_unlock(q->lock_ptr); - - ret = futex_handle_fault((unsigned long)uaddr, fshared, attempt++); - - spin_lock(q->lock_ptr); + ret = get_futex_value_locked(&uval, uaddr); - /* - * Check if someone else fixed it for us: - */ - if (pi_state->owner != oldowner) - return 0; + while (!ret) { + newval = (uval & FUTEX_OWNER_DIED) | newtid; - if (ret) - return ret; + curval = cmpxchg_futex_value_locked(uaddr, uval, newval); - goto retry; + if (curval == -EFAULT) + ret = -EFAULT; + if (curval == uval) + break; + uval = curval; + } + return ret; } /* @@ -1559,7 +1507,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, * that case: */ if (q.pi_state->owner != curr) - ret = fixup_pi_state_owner(uaddr, &q, curr, fshared); + ret = fixup_pi_state_owner(uaddr, &q, curr); } else { /* * Catch the rare case, where the lock was released @@ -1591,8 +1539,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, int res; owner = rt_mutex_owner(&q.pi_state->pi_mutex); - res = fixup_pi_state_owner(uaddr, &q, owner, - fshared); + res = fixup_pi_state_owner(uaddr, &q, owner); /* propagate -EFAULT, if the fixup failed */ if (res) diff --git a/trunk/kernel/kgdb.c b/trunk/kernel/kgdb.c index 3ec23c3ec97f..79e3c90113c2 100644 --- a/trunk/kernel/kgdb.c +++ b/trunk/kernel/kgdb.c @@ -1499,8 +1499,7 @@ int kgdb_nmicallback(int cpu, void *regs) return 1; } -static void kgdb_console_write(struct console *co, const char *s, - unsigned count) +void kgdb_console_write(struct console *co, const char *s, unsigned count) { unsigned long flags; diff --git a/trunk/kernel/rcuclassic.c b/trunk/kernel/rcuclassic.c index a38895a5b8e2..f4ffbd0f306f 100644 --- a/trunk/kernel/rcuclassic.c +++ b/trunk/kernel/rcuclassic.c @@ -89,22 +89,8 @@ static void force_quiescent_state(struct rcu_data *rdp, /* * Don't send IPI to itself. With irqs disabled, * rdp->cpu is the current cpu. - * - * cpu_online_map is updated by the _cpu_down() - * using stop_machine_run(). Since we're in irqs disabled - * section, stop_machine_run() is not exectuting, hence - * the cpu_online_map is stable. - * - * However, a cpu might have been offlined _just_ before - * we disabled irqs while entering here. - * And rcu subsystem might not yet have handled the CPU_DEAD - * notification, leading to the offlined cpu's bit - * being set in the rcp->cpumask. - * - * Hence cpumask = (rcp->cpumask & cpu_online_map) to prevent - * sending smp_reschedule() to an offlined CPU. */ - cpus_and(cpumask, rcp->cpumask, cpu_online_map); + cpumask = rcp->cpumask; cpu_clear(rdp->cpu, cpumask); for_each_cpu_mask(cpu, cpumask) smp_send_reschedule(cpu); diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index 94ead43eda62..b048ad8a11af 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -4398,20 +4398,22 @@ do_wait_for_common(struct completion *x, long timeout, int state) signal_pending(current)) || (state == TASK_KILLABLE && fatal_signal_pending(current))) { - timeout = -ERESTARTSYS; - break; + __remove_wait_queue(&x->wait, &wait); + return -ERESTARTSYS; } __set_current_state(state); spin_unlock_irq(&x->wait.lock); timeout = schedule_timeout(timeout); spin_lock_irq(&x->wait.lock); - } while (!x->done && timeout); + if (!timeout) { + __remove_wait_queue(&x->wait, &wait); + return timeout; + } + } while (!x->done); __remove_wait_queue(&x->wait, &wait); - if (!x->done) - return timeout; } x->done--; - return timeout ?: 1; + return timeout; } static long __sched @@ -5887,7 +5889,6 @@ static void migrate_dead_tasks(unsigned int dead_cpu) next = pick_next_task(rq, rq->curr); if (!next) break; - next->sched_class->put_prev_task(rq, next); migrate_dead(dead_cpu, next); } @@ -8502,9 +8503,6 @@ int sched_group_set_rt_period(struct task_group *tg, long rt_period_us) rt_period = (u64)rt_period_us * NSEC_PER_USEC; rt_runtime = tg->rt_bandwidth.rt_runtime; - if (rt_period == 0) - return -EINVAL; - return tg_set_bandwidth(tg, rt_period, rt_runtime); } diff --git a/trunk/kernel/sched_rt.c b/trunk/kernel/sched_rt.c index 0f3c19197fa4..1dad5bbb59b6 100644 --- a/trunk/kernel/sched_rt.c +++ b/trunk/kernel/sched_rt.c @@ -250,8 +250,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) if (rt_rq->rt_time || rt_rq->rt_nr_running) idle = 0; spin_unlock(&rt_rq->rt_runtime_lock); - } else if (rt_rq->rt_nr_running) - idle = 0; + } if (enqueue) sched_rt_rq_enqueue(rt_rq); diff --git a/trunk/lib/debugobjects.c b/trunk/lib/debugobjects.c index 85b18d79be89..a76a5e122ae1 100644 --- a/trunk/lib/debugobjects.c +++ b/trunk/lib/debugobjects.c @@ -68,7 +68,6 @@ static int fill_pool(void) { gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; struct debug_obj *new; - unsigned long flags; if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL)) return obj_pool_free; @@ -82,10 +81,10 @@ static int fill_pool(void) if (!new) return obj_pool_free; - spin_lock_irqsave(&pool_lock, flags); + spin_lock(&pool_lock); hlist_add_head(&new->node, &obj_pool); obj_pool_free++; - spin_unlock_irqrestore(&pool_lock, flags); + spin_unlock(&pool_lock); } return obj_pool_free; } @@ -111,13 +110,16 @@ static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b) } /* - * Allocate a new object. If the pool is empty, switch off the debugger. + * Allocate a new object. If the pool is empty and no refill possible, + * switch off the debugger. */ static struct debug_obj * alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) { struct debug_obj *obj = NULL; + int retry = 0; +repeat: spin_lock(&pool_lock); if (obj_pool.first) { obj = hlist_entry(obj_pool.first, typeof(*obj), node); @@ -139,6 +141,9 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) } spin_unlock(&pool_lock); + if (fill_pool() && !obj && !retry++) + goto repeat; + return obj; } @@ -256,8 +261,6 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) struct debug_obj *obj; unsigned long flags; - fill_pool(); - db = get_bucket((unsigned long) addr); spin_lock_irqsave(&db->lock, flags); diff --git a/trunk/lib/ts_bm.c b/trunk/lib/ts_bm.c index 4a7fce72898e..d90822c378a4 100644 --- a/trunk/lib/ts_bm.c +++ b/trunk/lib/ts_bm.c @@ -63,7 +63,7 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state) struct ts_bm *bm = ts_config_priv(conf); unsigned int i, text_len, consumed = state->offset; const u8 *text; - int shift = bm->patlen - 1, bs; + int shift = bm->patlen, bs; for (;;) { text_len = conf->get_next_block(consumed, &text, conf, state); diff --git a/trunk/mm/bootmem.c b/trunk/mm/bootmem.c index 8d9f60e06f62..e8fb927392b9 100644 --- a/trunk/mm/bootmem.c +++ b/trunk/mm/bootmem.c @@ -442,17 +442,15 @@ unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn, return init_bootmem_core(pgdat, freepfn, startpfn, endpfn); } -int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, +void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, unsigned long size, int flags) { int ret; ret = can_reserve_bootmem_core(pgdat->bdata, physaddr, size, flags); if (ret < 0) - return -ENOMEM; + return; reserve_bootmem_core(pgdat->bdata, physaddr, size, flags); - - return 0; } void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index d14b251a25a6..9aefaae46858 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1045,26 +1045,6 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, return page; } -/* Can we do the FOLL_ANON optimization? */ -static inline int use_zero_page(struct vm_area_struct *vma) -{ - /* - * We don't want to optimize FOLL_ANON for make_pages_present() - * when it tries to page in a VM_LOCKED region. As to VM_SHARED, - * we want to get the page from the page tables to make sure - * that we serialize and update with any other user of that - * mapping. - */ - if (vma->vm_flags & (VM_LOCKED | VM_SHARED)) - return 0; - /* - * And if we have a fault or a nopfn routine, it's not an - * anonymous region. - */ - return !vma->vm_ops || - (!vma->vm_ops->fault && !vma->vm_ops->nopfn); -} - int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int len, int write, int force, struct page **pages, struct vm_area_struct **vmas) @@ -1139,7 +1119,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, foll_flags = FOLL_TOUCH; if (pages) foll_flags |= FOLL_GET; - if (!write && use_zero_page(vma)) + if (!write && !(vma->vm_flags & VM_LOCKED) && + (!vma->vm_ops || !vma->vm_ops->fault)) foll_flags |= FOLL_ANON; do { @@ -1785,6 +1766,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, page_table = pte_offset_map_lock(mm, pmd, address, &ptl); if (likely(pte_same(*page_table, orig_pte))) { if (old_page) { + page_remove_rmap(old_page, vma); if (!PageAnon(old_page)) { dec_mm_counter(mm, file_rss); inc_mm_counter(mm, anon_rss); @@ -1806,32 +1788,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, lru_cache_add_active(new_page); page_add_new_anon_rmap(new_page, vma, address); - if (old_page) { - /* - * Only after switching the pte to the new page may - * we remove the mapcount here. Otherwise another - * process may come and find the rmap count decremented - * before the pte is switched to the new page, and - * "reuse" the old page writing into it while our pte - * here still points into it and can be read by other - * threads. - * - * The critical issue is to order this - * page_remove_rmap with the ptp_clear_flush above. - * Those stores are ordered by (if nothing else,) - * the barrier present in the atomic_add_negative - * in page_remove_rmap. - * - * Then the TLB flush in ptep_clear_flush ensures that - * no process can access the old page before the - * decremented mapcount is visible. And the old page - * cannot be reused until after the decremented - * mapcount is visible. So transitively, TLBs to - * old page will be flushed before it can be reused. - */ - page_remove_rmap(old_page, vma); - } - /* Free the old page.. */ new_page = old_page; ret |= VM_FAULT_WRITE; diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 046607f05f3e..06236e4ddc1b 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -3263,12 +3263,9 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags) if (cpuset_zone_allowed_hardwall(zone, flags) && cache->nodelists[nid] && - cache->nodelists[nid]->free_objects) { + cache->nodelists[nid]->free_objects) obj = ____cache_alloc_node(cache, flags | GFP_THISNODE, nid); - if (obj) - break; - } } if (!obj) { diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index fca23a3bf12c..68d8df0992ab 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -454,7 +454,7 @@ static int netdev_boot_setup_add(char *name, struct ifmap *map) for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { if (s[i].name[0] == '\0' || s[i].name[0] == ' ') { memset(s[i].name, 0, sizeof(s[i].name)); - strlcpy(s[i].name, name, IFNAMSIZ); + strcpy(s[i].name, name); memcpy(&s[i].map, map, sizeof(s[i].map)); break; } @@ -479,7 +479,7 @@ int netdev_boot_setup_check(struct net_device *dev) for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { if (s[i].name[0] != '\0' && s[i].name[0] != ' ' && - !strcmp(dev->name, s[i].name)) { + !strncmp(dev->name, s[i].name, strlen(s[i].name))) { dev->irq = s[i].map.irq; dev->base_addr = s[i].map.base_addr; dev->mem_start = s[i].map.mem_start; @@ -2077,10 +2077,6 @@ int netif_receive_skb(struct sk_buff *skb) rcu_read_lock(); - /* Don't receive packets in an exiting network namespace */ - if (!net_alive(dev_net(skb->dev))) - goto out; - #ifdef CONFIG_NET_CLS_ACT if (skb->tc_verd & TC_NCLS) { skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); @@ -2973,7 +2969,7 @@ EXPORT_SYMBOL(dev_unicast_delete); /** * dev_unicast_add - add a secondary unicast address * @dev: device - * @addr: address to add + * @addr: address to delete * @alen: length of @addr * * Add a secondary unicast address to the device or increase diff --git a/trunk/net/core/fib_rules.c b/trunk/net/core/fib_rules.c index 277a2302eb3a..e3e9ab0f74e3 100644 --- a/trunk/net/core/fib_rules.c +++ b/trunk/net/core/fib_rules.c @@ -226,7 +226,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) ops = lookup_rules_ops(net, frh->family); if (ops == NULL) { - err = -EAFNOSUPPORT; + err = EAFNOSUPPORT; goto errout; } @@ -365,7 +365,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) ops = lookup_rules_ops(net, frh->family); if (ops == NULL) { - err = -EAFNOSUPPORT; + err = EAFNOSUPPORT; goto errout; } diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index df3744355839..4f8369729a4e 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -68,6 +68,7 @@ static inline void *load_pointer(struct sk_buff *skb, int k, * sk_filter - run a packet through a socket filter * @sk: sock associated with &sk_buff * @skb: buffer to filter + * @needlock: set to 1 if the sock is not locked by caller. * * Run the filter code and then cut skb->data to correct size returned by * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller diff --git a/trunk/net/core/net_namespace.c b/trunk/net/core/net_namespace.c index 7c52fe277b62..72b4c184dd84 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -140,9 +140,6 @@ static void cleanup_net(struct work_struct *work) struct pernet_operations *ops; struct net *net; - /* Be very certain incoming network packets will not find us */ - rcu_barrier(); - net = container_of(work, struct net, work); mutex_lock(&net_mutex); diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 366621610e76..1e556d312117 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -1292,14 +1292,12 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, { unsigned int nr_pages = spd->nr_pages; unsigned int poff, plen, len, toff, tlen; - int headlen, seg, error = 0; + int headlen, seg; toff = *offset; tlen = *total_len; - if (!tlen) { - error = 1; + if (!tlen) goto err; - } /* * if the offset is greater than the linear part, go directly to @@ -1341,8 +1339,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, * just jump directly to update and return, no point * in going over fragments when the output is full. */ - error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb); - if (error) + if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb)) goto done; tlen -= plen; @@ -1372,8 +1369,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, if (!plen) break; - error = spd_fill_page(spd, f->page, plen, poff, skb); - if (error) + if (spd_fill_page(spd, f->page, plen, poff, skb)) break; tlen -= plen; @@ -1386,10 +1382,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, return 0; } err: - /* update the offset to reflect the linear part skip, if any */ - if (!error) - *offset = toff; - return error; + return 1; } /* diff --git a/trunk/net/ipv4/inet_fragment.c b/trunk/net/ipv4/inet_fragment.c index 0546a0bc97ea..4ed429bd5951 100644 --- a/trunk/net/ipv4/inet_fragment.c +++ b/trunk/net/ipv4/inet_fragment.c @@ -192,21 +192,14 @@ EXPORT_SYMBOL(inet_frag_evictor); static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, struct inet_frag_queue *qp_in, struct inet_frags *f, - void *arg) + unsigned int hash, void *arg) { struct inet_frag_queue *qp; #ifdef CONFIG_SMP struct hlist_node *n; #endif - unsigned int hash; write_lock(&f->lock); - /* - * While we stayed w/o the lock other CPU could update - * the rnd seed, so we need to re-calculate the hash - * chain. Fortunatelly the qp_in can be used to get one. - */ - hash = f->hashfn(qp_in); #ifdef CONFIG_SMP /* With SMP race we have to recheck hash table, because * such entry could be created on other cpu, while we @@ -254,7 +247,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, } static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, - struct inet_frags *f, void *arg) + struct inet_frags *f, void *arg, unsigned int hash) { struct inet_frag_queue *q; @@ -262,7 +255,7 @@ static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, if (q == NULL) return NULL; - return inet_frag_intern(nf, q, f, arg); + return inet_frag_intern(nf, q, f, hash, arg); } struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, @@ -271,6 +264,7 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, struct inet_frag_queue *q; struct hlist_node *n; + read_lock(&f->lock); hlist_for_each_entry(q, n, &f->hash[hash], list) { if (q->net == nf && f->match(q, key)) { atomic_inc(&q->refcnt); @@ -280,6 +274,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, } read_unlock(&f->lock); - return inet_frag_create(nf, f, key); + return inet_frag_create(nf, f, key, hash); } EXPORT_SYMBOL(inet_frag_find); diff --git a/trunk/net/ipv4/inet_lro.c b/trunk/net/ipv4/inet_lro.c index cfd034a2b96e..4a4d49fca1f2 100644 --- a/trunk/net/ipv4/inet_lro.c +++ b/trunk/net/ipv4/inet_lro.c @@ -383,7 +383,8 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, out2: /* send aggregated SKBs to stack */ lro_flush(lro_mgr, lro_desc); -out: +out: /* Original SKB has to be posted to stack */ + skb->ip_summed = lro_mgr->ip_summed; return 1; } diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 37221f659159..cd6ce6ac6358 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -229,8 +229,6 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user) arg.iph = iph; arg.user = user; - - read_lock(&ip4_frags.lock); hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash); diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 850825dc86e6..fc54a48fde1e 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -260,8 +260,6 @@ #include #include #include -#include -#include #include #include #include @@ -2622,7 +2620,7 @@ __setup("thash_entries=", set_thash_entries); void __init tcp_init(void) { struct sk_buff *skb = NULL; - unsigned long nr_pages, limit; + unsigned long limit; int order, i, max_share; BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); @@ -2691,9 +2689,8 @@ void __init tcp_init(void) * is up to 1/2 at 256 MB, decreasing toward zero with the amount of * memory, with a floor of 128 pages. */ - nr_pages = totalram_pages - totalhigh_pages; - limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); - limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); + limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); + limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); limit = max(limit, 128UL); sysctl_tcp_mem[0] = limit / 4 * 3; sysctl_tcp_mem[1] = limit; diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index ffe869ac1bcf..12695be2c255 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -2291,7 +2291,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) } seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " - "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n", + "%08X %5d %8d %lu %d %p %u %u %u %u %d%n", i, src, srcp, dest, destp, sk->sk_state, tp->write_seq - tp->snd_una, sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : @@ -2303,8 +2303,8 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) icsk->icsk_probes_out, sock_i_ino(sk), atomic_read(&sk->sk_refcnt), sk, - jiffies_to_clock_t(icsk->icsk_rto), - jiffies_to_clock_t(icsk->icsk_ack.ato), + icsk->icsk_rto, + icsk->icsk_ack.ato, (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, tp->snd_cwnd, tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, diff --git a/trunk/net/ipv6/ip6_input.c b/trunk/net/ipv6/ip6_input.c index 17eb48b8e329..4e5c8615832c 100644 --- a/trunk/net/ipv6/ip6_input.c +++ b/trunk/net/ipv6/ip6_input.c @@ -102,15 +102,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt if (hdr->version != 6) goto err; - /* - * RFC4291 2.5.3 - * A packet received on an interface with a destination address - * of loopback must be dropped. - */ - if (!(dev->flags & IFF_LOOPBACK) && - ipv6_addr_loopback(&hdr->daddr)) - goto err; - skb->transport_header = skb->network_header + sizeof(*hdr); IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); diff --git a/trunk/net/ipv6/ipv6_sockglue.c b/trunk/net/ipv6/ipv6_sockglue.c index 86e28a75267f..c042ce19bd14 100644 --- a/trunk/net/ipv6/ipv6_sockglue.c +++ b/trunk/net/ipv6/ipv6_sockglue.c @@ -345,21 +345,18 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, case IPV6_DSTOPTS: { struct ipv6_txoptions *opt; - - /* remove any sticky options header with a zero option - * length, per RFC3542. - */ if (optlen == 0) optval = NULL; - else if (optlen < sizeof(struct ipv6_opt_hdr) || - optlen & 0x7 || optlen > 8 * 255) - goto e_inval; /* hop-by-hop / destination options are privileged option */ retv = -EPERM; if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) break; + if (optlen < sizeof(struct ipv6_opt_hdr) || + optlen & 0x7 || optlen > 8 * 255) + goto e_inval; + opt = ipv6_renew_options(sk, np->opt, optname, (struct ipv6_opt_hdr __user *)optval, optlen); diff --git a/trunk/net/ipv6/netfilter/ip6table_mangle.c b/trunk/net/ipv6/netfilter/ip6table_mangle.c index f405cea21a8b..27a5e8b48d93 100644 --- a/trunk/net/ipv6/netfilter/ip6table_mangle.c +++ b/trunk/net/ipv6/netfilter/ip6table_mangle.c @@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = { .priority = NF_IP6_PRI_MANGLE, }, { - .hook = ip6t_route_hook, + .hook = ip6t_local_hook, .owner = THIS_MODULE, .pf = PF_INET6, .hooknum = NF_INET_LOCAL_IN, diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index cf20bc4fd60d..e65e26e210ee 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -207,10 +207,9 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) arg.id = id; arg.src = src; arg.dst = dst; - - read_lock_bh(&nf_frags.lock); hash = ip6qhashfn(id, src, dst); + local_bh_disable(); q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); local_bh_enable(); if (q == NULL) diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index a60d7d129713..798cabc7535b 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -247,8 +247,6 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, arg.id = id; arg.src = src; arg.dst = dst; - - read_lock(&ip6_frags.lock); hash = ip6qhashfn(id, src, dst); q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 7ff687020fa9..d1f3e19b06c7 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -240,7 +240,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr) static inline struct rt6_info *rt6_device_match(struct net *net, struct rt6_info *rt, int oif, - int flags) + int strict) { struct rt6_info *local = NULL; struct rt6_info *sprt; @@ -253,7 +253,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, if (dev->flags & IFF_LOOPBACK) { if (sprt->rt6i_idev == NULL || sprt->rt6i_idev->dev->ifindex != oif) { - if (flags & RT6_LOOKUP_F_IFACE && oif) + if (strict && oif) continue; if (local && (!oif || local->rt6i_idev->dev->ifindex == oif)) @@ -266,7 +266,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, if (local) return local; - if (flags & RT6_LOOKUP_F_IFACE) + if (strict) return net->ipv6.ip6_null_entry; } return rt; diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 40ea9c36d24b..cb46749d4c32 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -2036,7 +2036,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) seq_printf(seq, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n", + "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n", i, src->s6_addr32[0], src->s6_addr32[1], src->s6_addr32[2], src->s6_addr32[3], srcp, @@ -2052,8 +2052,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) icsk->icsk_probes_out, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, - jiffies_to_clock_t(icsk->icsk_rto), - jiffies_to_clock_t(icsk->icsk_ack.ato), + icsk->icsk_rto, + icsk->icsk_ack.ato, (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh ); diff --git a/trunk/net/mac80211/key.c b/trunk/net/mac80211/key.c index 220e83be3ef4..150d66dbda9d 100644 --- a/trunk/net/mac80211/key.c +++ b/trunk/net/mac80211/key.c @@ -380,15 +380,6 @@ void ieee80211_key_free(struct ieee80211_key *key) if (!key) return; - if (!key->sdata) { - /* The key has not been linked yet, simply free it - * and don't Oops */ - if (key->conf.alg == ALG_CCMP) - ieee80211_aes_key_free(key->u.ccmp.tfm); - kfree(key); - return; - } - spin_lock_irqsave(&key->sdata->local->key_lock, flags); __ieee80211_key_free(key); spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index c80d5899f279..28d8bd53bd3a 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -1132,7 +1132,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, ieee80211_tx_handler *handler; struct ieee80211_tx_data tx; ieee80211_tx_result res = TX_DROP, res_prepare; - int ret, i, retries = 0; + int ret, i; WARN_ON(__ieee80211_queue_pending(local, control->queue)); @@ -1216,13 +1216,6 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, if (!__ieee80211_queue_stopped(local, control->queue)) { clear_bit(IEEE80211_LINK_STATE_PENDING, &local->state[control->queue]); - retries++; - /* - * Driver bug, it's rejecting packets but - * not stopping queues. - */ - if (WARN_ON_ONCE(retries > 5)) - goto drop; goto retry; } memcpy(&store->control, control, diff --git a/trunk/net/mac80211/wext.c b/trunk/net/mac80211/wext.c index e8404212ad57..6106cb79060c 100644 --- a/trunk/net/mac80211/wext.c +++ b/trunk/net/mac80211/wext.c @@ -95,13 +95,6 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, } } - if (alg == ALG_WEP && - key_len != LEN_WEP40 && key_len != LEN_WEP104) { - ieee80211_key_free(key); - err = -EINVAL; - goto out_unlock; - } - ieee80211_key_link(key, sdata, sta); if (set_tx_key || (!sta && !sdata->default_key && key)) diff --git a/trunk/net/mac80211/wme.c b/trunk/net/mac80211/wme.c index 5d09e8698b57..635b996c8c35 100644 --- a/trunk/net/mac80211/wme.c +++ b/trunk/net/mac80211/wme.c @@ -323,7 +323,8 @@ static void wme_qdiscop_destroy(struct Qdisc* qd) struct ieee80211_hw *hw = &local->hw; int queue; - tcf_destroy_chain(&q->filter_list); + tcf_destroy_chain(q->filter_list); + q->filter_list = NULL; for (queue=0; queue < hw->queues; queue++) { skb_queue_purge(&q->requeued[queue]); diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 271cd01d57ae..ba94004fe323 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -331,13 +331,12 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph) I. Upper bound for valid data: seq <= sender.td_maxend II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin - III. Upper bound for valid (s)ack: sack <= receiver.td_end - IV. Lower bound for valid (s)ack: sack >= receiver.td_end - MAXACKWINDOW + III. Upper bound for valid ack: sack <= receiver.td_end + IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW - where sack is the highest right edge of sack block found in the packet - or ack in the case of packet without SACK option. + where sack is the highest right edge of sack block found in the packet. - The upper bound limit for a valid (s)ack is not ignored - + The upper bound limit for a valid ack is not ignored - we doesn't have to deal with fragments. */ @@ -607,12 +606,12 @@ static bool tcp_in_window(const struct nf_conn *ct, before(seq, sender->td_maxend + 1), after(end, sender->td_end - receiver->td_maxwin - 1), before(sack, receiver->td_end + 1), - after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)); + after(ack, receiver->td_end - MAXACKWINDOW(sender))); if (before(seq, sender->td_maxend + 1) && after(end, sender->td_end - receiver->td_maxwin - 1) && before(sack, receiver->td_end + 1) && - after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) { + after(ack, receiver->td_end - MAXACKWINDOW(sender))) { /* * Take into account window scaling (RFC 1323). */ diff --git a/trunk/net/netlabel/netlabel_unlabeled.c b/trunk/net/netlabel/netlabel_unlabeled.c index 52b2611a6eb6..0099da5b2591 100644 --- a/trunk/net/netlabel/netlabel_unlabeled.c +++ b/trunk/net/netlabel/netlabel_unlabeled.c @@ -1534,7 +1534,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, } } list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { - if (!addr6->valid || iter_addr6++ < skip_addr6) + if (addr6->valid || iter_addr6++ < skip_addr6) continue; if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, iface, diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index 349aba189558..9b97f8006c9c 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -886,7 +886,7 @@ int netlink_unicast(struct sock *ssk, struct sk_buff *skb, return netlink_unicast_kernel(sk, skb); if (sk_filter(sk, skb)) { - err = skb->len; + int err = skb->len; kfree_skb(skb); sock_put(sk); return err; diff --git a/trunk/net/netlink/attr.c b/trunk/net/netlink/attr.c index 2d106cfe1d27..47bbf45ae5d7 100644 --- a/trunk/net/netlink/attr.c +++ b/trunk/net/netlink/attr.c @@ -132,7 +132,6 @@ int nla_validate(struct nlattr *head, int len, int maxtype, * @maxtype: maximum attribute type to be expected * @head: head of attribute stream * @len: length of attribute stream - * @policy: validation policy * * Parses a stream of attributes and stores a pointer to each attribute in * the tb array accessable via the attribute type. Attributes with a type @@ -195,7 +194,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) /** * nla_strlcpy - Copy string attribute payload into a sized buffer * @dst: where to copy the string to - * @nla: attribute to copy the string from + * @src: attribute to copy the string from * @dstsize: size of destination buffer * * Copies at most dstsize - 1 bytes into the destination buffer. @@ -341,9 +340,9 @@ struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) } /** - * nla_reserve_nohdr - reserve room for attribute without header + * nla_reserve - reserve room for attribute without header * @skb: socket buffer to reserve room on - * @attrlen: length of attribute payload + * @len: length of attribute payload * * Reserves room for attribute payload without a header. * diff --git a/trunk/net/sched/Kconfig b/trunk/net/sched/Kconfig index 9437b27ff84d..82adfe6447d7 100644 --- a/trunk/net/sched/Kconfig +++ b/trunk/net/sched/Kconfig @@ -106,6 +106,17 @@ config NET_SCH_PRIO To compile this code as a module, choose M here: the module will be called sch_prio. +config NET_SCH_RR + tristate "Multi Band Round Robin Queuing (RR)" + select NET_SCH_PRIO + ---help--- + Say Y here if you want to use an n-band round robin packet + scheduler. + + The module uses sch_prio for its framework and is aliased as + sch_rr, so it will load sch_prio, although it is referred + to using sch_rr. + config NET_SCH_RED tristate "Random Early Detection (RED)" ---help--- diff --git a/trunk/net/sched/sch_api.c b/trunk/net/sched/sch_api.c index 10f01ad04380..c40773cdbe45 100644 --- a/trunk/net/sched/sch_api.c +++ b/trunk/net/sched/sch_api.c @@ -1252,12 +1252,12 @@ void tcf_destroy(struct tcf_proto *tp) kfree(tp); } -void tcf_destroy_chain(struct tcf_proto **fl) +void tcf_destroy_chain(struct tcf_proto *fl) { struct tcf_proto *tp; - while ((tp = *fl) != NULL) { - *fl = tp->next; + while ((tp = fl) != NULL) { + fl = tp->next; tcf_destroy(tp); } } diff --git a/trunk/net/sched/sch_atm.c b/trunk/net/sched/sch_atm.c index db0e23ae85f8..335273416384 100644 --- a/trunk/net/sched/sch_atm.c +++ b/trunk/net/sched/sch_atm.c @@ -160,7 +160,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl) *prev = flow->next; pr_debug("atm_tc_put: qdisc %p\n", flow->q); qdisc_destroy(flow->q); - tcf_destroy_chain(&flow->filter_list); + tcf_destroy_chain(flow->filter_list); if (flow->sock) { pr_debug("atm_tc_put: f_count %d\n", file_count(flow->sock->file)); @@ -586,11 +586,10 @@ static void atm_tc_destroy(struct Qdisc *sch) struct atm_flow_data *flow; pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p); - for (flow = p->flows; flow; flow = flow->next) - tcf_destroy_chain(&flow->filter_list); - /* races ? */ while ((flow = p->flows)) { + tcf_destroy_chain(flow->filter_list); + flow->filter_list = NULL; if (flow->ref > 1) printk(KERN_ERR "atm_destroy: %p->ref = %d\n", flow, flow->ref); diff --git a/trunk/net/sched/sch_cbq.c b/trunk/net/sched/sch_cbq.c index 2a3c97f7dc63..09969c1fbc08 100644 --- a/trunk/net/sched/sch_cbq.c +++ b/trunk/net/sched/sch_cbq.c @@ -1704,7 +1704,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) BUG_TRAP(!cl->filters); - tcf_destroy_chain(&cl->filter_list); + tcf_destroy_chain(cl->filter_list); qdisc_destroy(cl->q); qdisc_put_rtab(cl->R_tab); gen_kill_estimator(&cl->bstats, &cl->rate_est); @@ -1728,8 +1728,10 @@ cbq_destroy(struct Qdisc* sch) * be bound to classes which have been destroyed already. --TGR '04 */ for (h = 0; h < 16; h++) { - for (cl = q->classes[h]; cl; cl = cl->next) - tcf_destroy_chain(&cl->filter_list); + for (cl = q->classes[h]; cl; cl = cl->next) { + tcf_destroy_chain(cl->filter_list); + cl->filter_list = NULL; + } } for (h = 0; h < 16; h++) { struct cbq_class *next; diff --git a/trunk/net/sched/sch_dsmark.c b/trunk/net/sched/sch_dsmark.c index c4c1317cd47d..64465bacbe79 100644 --- a/trunk/net/sched/sch_dsmark.c +++ b/trunk/net/sched/sch_dsmark.c @@ -416,7 +416,7 @@ static void dsmark_destroy(struct Qdisc *sch) pr_debug("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); - tcf_destroy_chain(&p->filter_list); + tcf_destroy_chain(p->filter_list); qdisc_destroy(p->q); kfree(p->mask); } diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index 13afa7214392..d355e5e47fe3 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -468,7 +468,7 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) return sch; errout: - return ERR_PTR(err); + return ERR_PTR(-err); } struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, diff --git a/trunk/net/sched/sch_hfsc.c b/trunk/net/sched/sch_hfsc.c index e817aa00441d..fdfaa3fcc16d 100644 --- a/trunk/net/sched/sch_hfsc.c +++ b/trunk/net/sched/sch_hfsc.c @@ -1123,7 +1123,7 @@ hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) { struct hfsc_sched *q = qdisc_priv(sch); - tcf_destroy_chain(&cl->filter_list); + tcf_destroy_chain(cl->filter_list); qdisc_destroy(cl->qdisc); gen_kill_estimator(&cl->bstats, &cl->rate_est); if (cl != &q->root) @@ -1540,10 +1540,6 @@ hfsc_destroy_qdisc(struct Qdisc *sch) struct hfsc_class *cl, *next; unsigned int i; - for (i = 0; i < HFSC_HSIZE; i++) { - list_for_each_entry(cl, &q->clhash[i], hlist) - tcf_destroy_chain(&cl->filter_list); - } for (i = 0; i < HFSC_HSIZE; i++) { list_for_each_entry_safe(cl, next, &q->clhash[i], hlist) hfsc_destroy_class(sch, cl); diff --git a/trunk/net/sched/sch_htb.c b/trunk/net/sched/sch_htb.c index 3fb58f428f72..6807c97985a5 100644 --- a/trunk/net/sched/sch_htb.c +++ b/trunk/net/sched/sch_htb.c @@ -1238,7 +1238,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) qdisc_put_rtab(cl->rate); qdisc_put_rtab(cl->ceil); - tcf_destroy_chain(&cl->filter_list); + tcf_destroy_chain(cl->filter_list); while (!list_empty(&cl->children)) htb_destroy_class(sch, list_entry(cl->children.next, @@ -1267,7 +1267,7 @@ static void htb_destroy(struct Qdisc *sch) and surprisingly it worked in 2.4. But it must precede it because filter need its target class alive to be able to call unbind_filter on it (without Oops). */ - tcf_destroy_chain(&q->filter_list); + tcf_destroy_chain(q->filter_list); while (!list_empty(&q->root)) htb_destroy_class(sch, list_entry(q->root.next, diff --git a/trunk/net/sched/sch_ingress.c b/trunk/net/sched/sch_ingress.c index 956c80ad5965..274b1ddb160c 100644 --- a/trunk/net/sched/sch_ingress.c +++ b/trunk/net/sched/sch_ingress.c @@ -104,7 +104,7 @@ static void ingress_destroy(struct Qdisc *sch) { struct ingress_qdisc_data *p = qdisc_priv(sch); - tcf_destroy_chain(&p->filter_list); + tcf_destroy_chain(p->filter_list); } static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) diff --git a/trunk/net/sched/sch_prio.c b/trunk/net/sched/sch_prio.c index 5532f1031ab5..4aa2b45dad0a 100644 --- a/trunk/net/sched/sch_prio.c +++ b/trunk/net/sched/sch_prio.c @@ -219,7 +219,7 @@ prio_destroy(struct Qdisc* sch) int prio; struct prio_sched_data *q = qdisc_priv(sch); - tcf_destroy_chain(&q->filter_list); + tcf_destroy_chain(q->filter_list); for (prio=0; priobands; prio++) qdisc_destroy(q->queues[prio]); } diff --git a/trunk/net/sched/sch_sfq.c b/trunk/net/sched/sch_sfq.c index 6a97afbfb952..f0463d757a98 100644 --- a/trunk/net/sched/sch_sfq.c +++ b/trunk/net/sched/sch_sfq.c @@ -520,7 +520,7 @@ static void sfq_destroy(struct Qdisc *sch) { struct sfq_sched_data *q = qdisc_priv(sch); - tcf_destroy_chain(&q->filter_list); + tcf_destroy_chain(q->filter_list); q->perturb_period = 0; del_timer_sync(&q->perturb_timer); } diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 0dbcde6758ea..e7e3baf7009e 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -4401,9 +4401,7 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; - if (getaddrs.addr_num <= 0 || - getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) - return -EINVAL; + if (getaddrs.addr_num <= 0) return -EINVAL; /* * For UDP-style sockets, id specifies the association to query. * If the id field is set to the value '0' then the locally bound diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 783317dacd30..657835f227d3 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -487,8 +487,8 @@ static int unix_socketpair(struct socket *, struct socket *); static int unix_accept(struct socket *, struct socket *, int); static int unix_getname(struct socket *, struct sockaddr *, int *, int); static unsigned int unix_poll(struct file *, struct socket *, poll_table *); -static unsigned int unix_dgram_poll(struct file *, struct socket *, - poll_table *); +static unsigned int unix_datagram_poll(struct file *, struct socket *, + poll_table *); static int unix_ioctl(struct socket *, unsigned int, unsigned long); static int unix_shutdown(struct socket *, int); static int unix_stream_sendmsg(struct kiocb *, struct socket *, @@ -534,7 +534,7 @@ static const struct proto_ops unix_dgram_ops = { .socketpair = unix_socketpair, .accept = sock_no_accept, .getname = unix_getname, - .poll = unix_dgram_poll, + .poll = unix_datagram_poll, .ioctl = unix_ioctl, .listen = sock_no_listen, .shutdown = unix_shutdown, @@ -555,7 +555,7 @@ static const struct proto_ops unix_seqpacket_ops = { .socketpair = unix_socketpair, .accept = unix_accept, .getname = unix_getname, - .poll = unix_dgram_poll, + .poll = unix_datagram_poll, .ioctl = unix_ioctl, .listen = unix_listen, .shutdown = unix_shutdown, @@ -1994,13 +1994,29 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl return mask; } -static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, - poll_table *wait) +static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, + poll_table *wait) { - struct sock *sk = sock->sk, *other; - unsigned int mask, writable; + struct sock *sk = sock->sk, *peer; + unsigned int mask; poll_wait(file, sk->sk_sleep, wait); + + peer = unix_peer_get(sk); + if (peer) { + if (peer != sk) { + /* + * Writability of a connected socket additionally + * depends on the state of the receive queue of the + * peer. + */ + poll_wait(file, &unix_sk(peer)->peer_wait, wait); + } else { + sock_put(peer); + peer = NULL; + } + } + mask = 0; /* exceptional events? */ @@ -2026,26 +2042,14 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, } /* writable? */ - writable = unix_writable(sk); - if (writable) { - other = unix_peer_get(sk); - if (other) { - if (unix_peer(other) != sk) { - poll_wait(file, &unix_sk(other)->peer_wait, - wait); - if (unix_recvq_full(other)) - writable = 0; - } - - sock_put(other); - } - } - - if (writable) + if (unix_writable(sk) && !(peer && unix_recvq_full(peer))) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; else set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); + if (peer) + sock_put(peer); + return mask; } diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index 855bff4b3250..185488da2466 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -80,23 +80,6 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = { IEEE80211_CHAN_RADAR), }; -static const struct ieee80211_channel_range ieee80211_EU_channels[] = { - /* IEEE 802.11b/g, channels 1..13 */ - RANGE_PWR(2412, 2472, 20, 6, 0), - /* IEEE 802.11a, channel 36*/ - RANGE_PWR(5180, 5180, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), - /* IEEE 802.11a, channel 40*/ - RANGE_PWR(5200, 5200, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), - /* IEEE 802.11a, channel 44*/ - RANGE_PWR(5220, 5220, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), - /* IEEE 802.11a, channels 48..64 */ - RANGE_PWR(5240, 5320, 23, 6, IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR), - /* IEEE 802.11a, channels 100..140 */ - RANGE_PWR(5500, 5700, 30, 6, IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR), -}; - #define REGDOM(_code) \ { \ .code = __stringify(_code), \ @@ -107,7 +90,6 @@ static const struct ieee80211_channel_range ieee80211_EU_channels[] = { static const struct ieee80211_regdomain ieee80211_regdoms[] = { REGDOM(US), REGDOM(JP), - REGDOM(EU), }; diff --git a/trunk/sound/isa/sb/sb_mixer.c b/trunk/sound/isa/sb/sb_mixer.c index 73d4572d136b..91d14224f6b3 100644 --- a/trunk/sound/isa/sb/sb_mixer.c +++ b/trunk/sound/isa/sb/sb_mixer.c @@ -925,7 +925,7 @@ static unsigned char als4000_saved_regs[] = { static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) { unsigned char *val = chip->saved_regs; - snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); + snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return); for (; num_regs; num_regs--) *val++ = snd_sbmixer_read(chip, *regs++); } @@ -933,7 +933,7 @@ static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs) { unsigned char *val = chip->saved_regs; - snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return); + snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return); for (; num_regs; num_regs--) snd_sbmixer_write(chip, *regs++, *val++); } diff --git a/trunk/sound/pci/aw2/aw2-alsa.c b/trunk/sound/pci/aw2/aw2-alsa.c index 3f00ddf450f8..56f87cd33c19 100644 --- a/trunk/sound/pci/aw2/aw2-alsa.c +++ b/trunk/sound/pci/aw2/aw2-alsa.c @@ -316,8 +316,6 @@ static int __devinit snd_aw2_create(struct snd_card *card, return -ENOMEM; } - /* (2) initialization of the chip hardware */ - snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); if (request_irq(pci->irq, snd_aw2_saa7146_interrupt, IRQF_SHARED, "Audiowerk2", chip)) { @@ -331,6 +329,8 @@ static int __devinit snd_aw2_create(struct snd_card *card, } chip->irq = pci->irq; + /* (2) initialization of the chip hardware */ + snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); if (err < 0) { free_irq(chip->irq, (void *)chip); diff --git a/trunk/virt/kvm/ioapic.c b/trunk/virt/kvm/ioapic.c index 1dcf9f3d1107..98778cb69c6e 100644 --- a/trunk/virt/kvm/ioapic.c +++ b/trunk/virt/kvm/ioapic.c @@ -269,9 +269,28 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) } } -static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi) +static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector) { + int i; + + for (i = 0; i < IOAPIC_NUM_PINS; i++) + if (ioapic->redirtbl[i].fields.vector == vector) + return i; + return -1; +} + +void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) +{ + struct kvm_ioapic *ioapic = kvm->arch.vioapic; union ioapic_redir_entry *ent; + int gsi; + + gsi = get_eoi_gsi(ioapic, vector); + if (gsi == -1) { + printk(KERN_WARNING "Can't find redir item for %d EOI\n", + vector); + return; + } ent = &ioapic->redirtbl[gsi]; ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); @@ -281,16 +300,6 @@ static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi) ioapic_deliver(ioapic, gsi); } -void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) -{ - struct kvm_ioapic *ioapic = kvm->arch.vioapic; - int i; - - for (i = 0; i < IOAPIC_NUM_PINS; i++) - if (ioapic->redirtbl[i].fields.vector == vector) - __kvm_ioapic_update_eoi(ioapic, i); -} - static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr) { struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;