Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 7 Jul 2011 20:18:13 +0000 (13:18 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 7 Jul 2011 20:18:13 +0000 (13:18 -0700)
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: Don't use the EFI reboot method by default
  x86, suspend: Restore MISC_ENABLE MSR in realmode wakeup
  x86, reboot: Acer Aspire One A110 reboot quirk
  x86-32, NUMA: Fix boot regression caused by NUMA init unification on highmem machines

205 files changed:
CREDITS
Documentation/CodingStyle
Documentation/cgroups/blkio-controller.txt
Documentation/hwmon/f71882fg
Documentation/hwmon/k10temp
Documentation/power/runtime_pm.txt
MAINTAINERS
Makefile
README
arch/arm/mach-at91/at91cap9.c
arch/arm/mach-at91/at91cap9_devices.c
arch/arm/mach-at91/at91rm9200.c
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91sam9260_devices.c
arch/arm/mach-at91/at91sam9261_devices.c
arch/arm/mach-at91/at91sam9263_devices.c
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/at91sam9rl.c
arch/arm/mach-at91/at91sam9rl_devices.c
arch/arm/mach-at91/board-cap9adk.c
arch/arm/mach-at91/board-sam9260ek.c
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-at91/board-sam9g20ek.c
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/include/mach/system_rev.h
arch/x86/oprofile/nmi_int.c
arch/x86/pci/xen.c
arch/x86/xen/mmu.c
drivers/gpio/tps65910-gpio.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/nid.h
drivers/hwmon/Kconfig
drivers/hwmon/adm1275.c
drivers/hwmon/emc6w201.c
drivers/hwmon/f71882fg.c
drivers/hwmon/hwmon-vid.c
drivers/hwmon/pmbus.c
drivers/hwmon/pmbus_core.c
drivers/hwmon/sch5627.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/uverbs_main.c
drivers/input/keyboard/pmic8xxx-keypad.c
drivers/input/misc/pmic8xxx-pwrkey.c
drivers/media/rc/fintek-cir.c
drivers/media/rc/imon.c
drivers/media/rc/ir-raw.c
drivers/media/rc/ite-cir.c
drivers/media/rc/ite-cir.h
drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
drivers/media/rc/lirc_dev.c
drivers/media/rc/mceusb.c
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/nuvoton-cir.h
drivers/media/rc/rc-main.c
drivers/media/video/m5mols/m5mols.h
drivers/media/video/m5mols/m5mols_capture.c
drivers/media/video/m5mols/m5mols_controls.c
drivers/media/video/m5mols/m5mols_core.c
drivers/media/video/m5mols/m5mols_reg.h
drivers/media/video/mx1_camera.c
drivers/media/video/omap/omap_vout.c
drivers/media/video/omap/omap_voutlib.c
drivers/media/video/omap3isp/isp.c
drivers/media/video/pwc/pwc-ctrl.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/pwc/pwc.h
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/s5p-fimc/fimc-core.c
drivers/media/video/s5p-fimc/fimc-core.h
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/uvc/uvc_entity.c
drivers/media/video/uvc/uvc_queue.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/v4l2-dev.c
drivers/media/video/videobuf2-core.c
drivers/media/video/videobuf2-dma-sg.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/omap-usb-host.c
drivers/mfd/tps65911-comparator.c
drivers/net/8139too.c
drivers/net/bna/bnad.c
drivers/net/greth.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/natsemi.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_main.c
drivers/net/sh_eth.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/wireless/ath/ath5k/eeprom.c
drivers/net/wireless/ath/ath9k/pci.c
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/hpsa.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/isci/Makefile [new file with mode: 0644]
drivers/scsi/isci/firmware/Makefile [new file with mode: 0644]
drivers/scsi/isci/firmware/README [new file with mode: 0644]
drivers/scsi/isci/firmware/create_fw.c [new file with mode: 0644]
drivers/scsi/isci/firmware/create_fw.h [new file with mode: 0644]
drivers/scsi/isci/host.c [new file with mode: 0644]
drivers/scsi/isci/host.h [new file with mode: 0644]
drivers/scsi/isci/init.c [new file with mode: 0644]
drivers/scsi/isci/isci.h [new file with mode: 0644]
drivers/scsi/isci/phy.c [new file with mode: 0644]
drivers/scsi/isci/phy.h [new file with mode: 0644]
drivers/scsi/isci/port.c [new file with mode: 0644]
drivers/scsi/isci/port.h [new file with mode: 0644]
drivers/scsi/isci/port_config.c [new file with mode: 0644]
drivers/scsi/isci/probe_roms.c [new file with mode: 0644]
drivers/scsi/isci/probe_roms.h [new file with mode: 0644]
drivers/scsi/isci/registers.h [new file with mode: 0644]
drivers/scsi/isci/remote_device.c [new file with mode: 0644]
drivers/scsi/isci/remote_device.h [new file with mode: 0644]
drivers/scsi/isci/remote_node_context.c [new file with mode: 0644]
drivers/scsi/isci/remote_node_context.h [new file with mode: 0644]
drivers/scsi/isci/remote_node_table.c [new file with mode: 0644]
drivers/scsi/isci/remote_node_table.h [new file with mode: 0644]
drivers/scsi/isci/request.c [new file with mode: 0644]
drivers/scsi/isci/request.h [new file with mode: 0644]
drivers/scsi/isci/sas.h [new file with mode: 0644]
drivers/scsi/isci/scu_completion_codes.h [new file with mode: 0644]
drivers/scsi/isci/scu_event_codes.h [new file with mode: 0644]
drivers/scsi/isci/scu_remote_node_context.h [new file with mode: 0644]
drivers/scsi/isci/scu_task_context.h [new file with mode: 0644]
drivers/scsi/isci/task.c [new file with mode: 0644]
drivers/scsi/isci/task.h [new file with mode: 0644]
drivers/scsi/isci/unsolicited_frame_control.c [new file with mode: 0644]
drivers/scsi/isci/unsolicited_frame_control.h [new file with mode: 0644]
drivers/staging/lirc/lirc_imon.c
drivers/staging/lirc/lirc_serial.c
drivers/staging/lirc/lirc_sir.c
drivers/staging/lirc/lirc_zilog.c
drivers/tty/serial/atmel_serial.c
drivers/usb/core/message.c
drivers/usb/gadget/fsl_udc_core.c
drivers/video/amba-clcd.c
drivers/video/fsl-diu-fb.c
drivers/video/geode/gx1fb_core.c
drivers/video/hecubafb.c
drivers/video/sh_mobile_meram.c
drivers/video/sm501fb.c
drivers/video/udlfb.c
drivers/video/vesafb.c
firmware/Makefile
firmware/isci/isci_firmware.bin.ihex [new file with mode: 0644]
fs/binfmt_elf_fdpic.c
fs/ceph/file.c
fs/cifs/connect.c
fs/hfsplus/super.c
fs/hfsplus/wrapper.c
fs/locks.c
include/linux/fsl-diu-fb.h
include/linux/sched.h
include/media/lirc_dev.h
include/media/m5mols.h
include/net/cfg80211.h
include/net/dst.h
include/sound/sb16_csp.h
kernel/jump_label.c
kernel/resource.c
kernel/sched.c
lib/debugobjects.c
net/8021q/vlan_dev.c
net/bridge/br_device.c
net/bridge/br_input.c
net/ceph/osd_client.c
net/core/dst.c
net/ipv4/af_inet.c
net/ipv4/ip_output.c
net/ipv4/tcp.c
net/ipv4/udp.c
net/ipv4/xfrm4_output.c
net/ipv6/af_inet6.c
net/ipv6/route.c
net/mac80211/wpa.c
net/sctp/protocol.c
net/sctp/socket.c
net/wireless/nl80211.c
net/xfrm/xfrm_policy.c
sound/atmel/abdac.c
sound/atmel/ac97c.c
sound/pci/cs5535audio/cs5535audio_pcm.c
sound/pci/hda/hda_eld.c
sound/pci/hda/patch_conexant.c
sound/pci/rme9652/hdspm.c
sound/spi/at73c213.c

diff --git a/CREDITS b/CREDITS
index d78359f..1deb331 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -518,7 +518,7 @@ N: Zach Brown
 E: zab@zabbo.net
 D: maestro pci sound
 
-M: David Brownell
+N: David Brownell
 D: Kernel engineer, mentor, and friend.  Maintained USB EHCI and
 D: gadget layers, SPI subsystem, GPIO subsystem, and more than a few
 D: device drivers.  His encouragement also helped many engineers get
index 58b0bf9..fa6e25b 100644 (file)
@@ -680,8 +680,8 @@ ones already enabled by DEBUG.
                Chapter 14: Allocating memory
 
 The kernel provides the following general purpose memory allocators:
-kmalloc(), kzalloc(), kcalloc(), and vmalloc().  Please refer to the API
-documentation for further information about them.
+kmalloc(), kzalloc(), kcalloc(), vmalloc(), and vzalloc().  Please refer to
+the API documentation for further information about them.
 
 The preferred form for passing a size of a struct is the following:
 
index cd45c8e..84f0a15 100644 (file)
@@ -77,7 +77,7 @@ Throttling/Upper Limit policy
 - Specify a bandwidth rate on particular device for root group. The format
   for policy is "<major>:<minor>  <byes_per_second>".
 
-        echo "8:16  1048576" > /sys/fs/cgroup/blkio/blkio.read_bps_device
+        echo "8:16  1048576" > /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device
 
   Above will put a limit of 1MB/second on reads happening for root group
   on device having major/minor number 8:16.
@@ -90,7 +90,7 @@ Throttling/Upper Limit policy
         1024+0 records out
         4194304 bytes (4.2 MB) copied, 4.0001 s, 1.0 MB/s
 
- Limits for writes can be put using blkio.write_bps_device file.
+ Limits for writes can be put using blkio.throttle.write_bps_device file.
 
 Hierarchical Cgroups
 ====================
@@ -286,28 +286,28 @@ Throttling/Upper limit policy files
          specified in bytes per second. Rules are per deivce. Following is
          the format.
 
-  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.read_bps_device
+  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.throttle.read_bps_device
 
 - blkio.throttle.write_bps_device
        - Specifies upper limit on WRITE rate to the device. IO rate is
          specified in bytes per second. Rules are per deivce. Following is
          the format.
 
-  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.write_bps_device
+  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.throttle.write_bps_device
 
 - blkio.throttle.read_iops_device
        - Specifies upper limit on READ rate from the device. IO rate is
          specified in IO per second. Rules are per deivce. Following is
          the format.
 
-  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.read_iops_device
+  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.throttle.read_iops_device
 
 - blkio.throttle.write_iops_device
        - Specifies upper limit on WRITE rate to the device. IO rate is
          specified in io per second. Rules are per deivce. Following is
          the format.
 
-  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.write_iops_device
+  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.throttle.write_iops_device
 
 Note: If both BW and IOPS rules are specified for a device, then IO is
       subjectd to both the constraints.
index 84d2623..de91c0d 100644 (file)
@@ -22,6 +22,10 @@ Supported chips:
     Prefix: 'f71869'
     Addresses scanned: none, address read from Super I/O config space
     Datasheet: Available from the Fintek website
+  * Fintek F71869A
+    Prefix: 'f71869a'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71882FG and F71883FG
     Prefix: 'f71882fg'
     Addresses scanned: none, address read from Super I/O config space
index 0393c89..a10f736 100644 (file)
@@ -9,8 +9,8 @@ Supported chips:
   Socket S1G3: Athlon II, Sempron, Turion II
 * AMD Family 11h processors:
   Socket S1G2: Athlon (X2), Sempron (X2), Turion X2 (Ultra)
-* AMD Family 12h processors: "Llano"
-* AMD Family 14h processors: "Brazos" (C/E/G-Series)
+* AMD Family 12h processors: "Llano" (E2/A4/A6/A8-Series)
+* AMD Family 14h processors: "Brazos" (C/E/G/Z-Series)
 * AMD Family 15h processors: "Bulldozer"
 
   Prefix: 'k10temp'
@@ -20,12 +20,16 @@ Supported chips:
     http://support.amd.com/us/Processor_TechDocs/31116.pdf
   BIOS and Kernel Developer's Guide (BKDG) for AMD Family 11h Processors:
     http://support.amd.com/us/Processor_TechDocs/41256.pdf
+  BIOS and Kernel Developer's Guide (BKDG) for AMD Family 12h Processors:
+    http://support.amd.com/us/Processor_TechDocs/41131.pdf
   BIOS and Kernel Developer's Guide (BKDG) for AMD Family 14h Models 00h-0Fh Processors:
     http://support.amd.com/us/Processor_TechDocs/43170.pdf
   Revision Guide for AMD Family 10h Processors:
     http://support.amd.com/us/Processor_TechDocs/41322.pdf
   Revision Guide for AMD Family 11h Processors:
     http://support.amd.com/us/Processor_TechDocs/41788.pdf
+  Revision Guide for AMD Family 12h Processors:
+    http://support.amd.com/us/Processor_TechDocs/44739.pdf
   Revision Guide for AMD Family 14h Models 00h-0Fh Processors:
     http://support.amd.com/us/Processor_TechDocs/47534.pdf
   AMD Family 11h Processor Power and Thermal Data Sheet for Notebooks:
index 22accb3..b24875b 100644 (file)
@@ -501,13 +501,29 @@ helper functions described in Section 4.  In that case, pm_runtime_resume()
 should be used.  Of course, for this purpose the device's run-time PM has to be
 enabled earlier by calling pm_runtime_enable().
 
-If the device bus type's or driver's ->probe() or ->remove() callback runs
+If the device bus type's or driver's ->probe() callback runs
 pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts,
 they will fail returning -EAGAIN, because the device's usage counter is
-incremented by the core before executing ->probe() and ->remove().  Still, it
-may be desirable to suspend the device as soon as ->probe() or ->remove() has
-finished, so the PM core uses pm_runtime_idle_sync() to invoke the
-subsystem-level idle callback for the device at that time.
+incremented by the driver core before executing ->probe().  Still, it may be
+desirable to suspend the device as soon as ->probe() has finished, so the driver
+core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for
+the device at that time.
+
+Moreover, the driver core prevents runtime PM callbacks from racing with the bus
+notifier callback in __device_release_driver(), which is necessary, because the
+notifier is used by some subsystems to carry out operations affecting the
+runtime PM functionality.  It does so by calling pm_runtime_get_sync() before
+driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications.  This
+resumes the device if it's in the suspended state and prevents it from
+being suspended again while those routines are being executed.
+
+To allow bus types and drivers to put devices into the suspended state by
+calling pm_runtime_suspend() from their ->remove() routines, the driver core
+executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER
+notifications in __device_release_driver().  This requires bus types and
+drivers to make their ->remove() callbacks avoid races with runtime PM directly,
+but also it allows of more flexibility in the handling of devices during the
+removal of their drivers.
 
 The user space can effectively disallow the driver of the device to power manage
 it at run time by changing the value of its /sys/devices/.../power/control
index ae563fa..9820e89 100644 (file)
@@ -2197,7 +2197,7 @@ F:        drivers/acpi/dock.c
 DOCUMENTATION
 M:     Randy Dunlap <rdunlap@xenotime.net>
 L:     linux-doc@vger.kernel.org
-T:     quilt oss.oracle.com/~rdunlap/kernel-doc-patches/current/
+T:     quilt http://userweb.kernel.org/~rdunlap/kernel-doc-patches/current/
 S:     Maintained
 F:     Documentation/
 
@@ -6733,6 +6733,7 @@ F:        fs/fat/
 VIDEOBUF2 FRAMEWORK
 M:     Pawel Osciak <pawel@osciak.com>
 M:     Marek Szyprowski <m.szyprowski@samsung.com>
+M:     Kyungmin Park <kyungmin.park@samsung.com>
 L:     linux-media@vger.kernel.org
 S:     Maintained
 F:     drivers/media/video/videobuf2-*
index dc67046..86f47a0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Sneaky Weasel
 
 # *DOCUMENTATION*
diff --git a/README b/README
index 8510017..0d5a7dd 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
-       Linux kernel release 2.6.xx <http://kernel.org/>
+       Linux kernel release 3.x <http://kernel.org/>
 
-These are the release notes for Linux version 2.6.  Read them carefully,
+These are the release notes for Linux version 3.  Read them carefully,
 as they tell you what this is all about, explain how to install the
 kernel, and what to do if something goes wrong. 
 
@@ -62,10 +62,10 @@ INSTALLING the kernel source:
    directory where you have permissions (eg. your home directory) and
    unpack it:
 
-               gzip -cd linux-2.6.XX.tar.gz | tar xvf -
+               gzip -cd linux-3.X.tar.gz | tar xvf -
 
    or
-               bzip2 -dc linux-2.6.XX.tar.bz2 | tar xvf -
+               bzip2 -dc linux-3.X.tar.bz2 | tar xvf -
 
 
    Replace "XX" with the version number of the latest kernel.
@@ -75,15 +75,15 @@ INSTALLING the kernel source:
    files.  They should match the library, and not get messed up by
    whatever the kernel-du-jour happens to be.
 
- - You can also upgrade between 2.6.xx releases by patching.  Patches are
+ - You can also upgrade between 3.x releases by patching.  Patches are
    distributed in the traditional gzip and the newer bzip2 format.  To
    install by patching, get all the newer patch files, enter the
-   top level directory of the kernel source (linux-2.6.xx) and execute:
+   top level directory of the kernel source (linux-3.x) and execute:
 
-               gzip -cd ../patch-2.6.xx.gz | patch -p1
+               gzip -cd ../patch-3.x.gz | patch -p1
 
    or
-               bzip2 -dc ../patch-2.6.xx.bz2 | patch -p1
+               bzip2 -dc ../patch-3.x.bz2 | patch -p1
 
    (repeat xx for all versions bigger than the version of your current
    source tree, _in_order_) and you should be ok.  You may want to remove
@@ -91,9 +91,9 @@ INSTALLING the kernel source:
    failed patches (xxx# or xxx.rej). If there are, either you or me has
    made a mistake.
 
-   Unlike patches for the 2.6.x kernels, patches for the 2.6.x.y kernels
+   Unlike patches for the 3.x kernels, patches for the 3.x.y kernels
    (also known as the -stable kernels) are not incremental but instead apply
-   directly to the base 2.6.x kernel.  Please read
+   directly to the base 3.x kernel.  Please read
    Documentation/applying-patches.txt for more information.
 
    Alternatively, the script patch-kernel can be used to automate this
@@ -107,14 +107,14 @@ INSTALLING the kernel source:
    an alternative directory can be specified as the second argument.
 
  - If you are upgrading between releases using the stable series patches
-   (for example, patch-2.6.xx.y), note that these "dot-releases" are
-   not incremental and must be applied to the 2.6.xx base tree. For
-   example, if your base kernel is 2.6.12 and you want to apply the
-   2.6.12.3 patch, you do not and indeed must not first apply the
-   2.6.12.1 and 2.6.12.2 patches. Similarly, if you are running kernel
-   version 2.6.12.2 and want to jump to 2.6.12.3, you must first
-   reverse the 2.6.12.2 patch (that is, patch -R) _before_ applying
-   the 2.6.12.3 patch.
+   (for example, patch-3.x.y), note that these "dot-releases" are
+   not incremental and must be applied to the 3.x base tree. For
+   example, if your base kernel is 3.0 and you want to apply the
+   3.0.3 patch, you do not and indeed must not first apply the
+   3.0.1 and 3.0.2 patches. Similarly, if you are running kernel
+   version 3.0.2 and want to jump to 3.0.3, you must first
+   reverse the 3.0.2 patch (that is, patch -R) _before_ applying
+   the 3.0.3 patch.
    You can read more on this in Documentation/applying-patches.txt
 
  - Make sure you have no stale .o files and dependencies lying around:
@@ -126,7 +126,7 @@ INSTALLING the kernel source:
 
 SOFTWARE REQUIREMENTS
 
-   Compiling and running the 2.6.xx kernels requires up-to-date
+   Compiling and running the 3.x kernels requires up-to-date
    versions of various software packages.  Consult
    Documentation/Changes for the minimum version numbers required
    and how to get updates for these packages.  Beware that using
@@ -142,11 +142,11 @@ BUILD directory for the kernel:
    Using the option "make O=output/dir" allow you to specify an alternate
    place for the output files (including .config).
    Example:
-     kernel source code:       /usr/src/linux-2.6.N
+     kernel source code:       /usr/src/linux-3.N
      build directory:          /home/name/build/kernel
 
    To configure and build the kernel use:
-   cd /usr/src/linux-2.6.N
+   cd /usr/src/linux-3.N
    make O=/home/name/build/kernel menuconfig
    make O=/home/name/build/kernel
    sudo make O=/home/name/build/kernel modules_install install
index 17fae4a..f1013d0 100644 (file)
@@ -223,15 +223,15 @@ static struct clk *periph_clocks[] __initdata = {
 };
 
 static struct clk_lookup periph_clocks_lookups[] = {
-       CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc.0", &utmi_clk),
-       CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc.0", &udphs_clk),
+       CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+       CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
        CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
        CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
        CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
        CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
        CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
-       CLKDEV_CON_DEV_ID("ssc", "ssc.0", &ssc0_clk),
-       CLKDEV_CON_DEV_ID("ssc", "ssc.1", &ssc1_clk),
+       CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+       CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
 };
 
 static struct clk_lookup usart_clocks_lookups[] = {
index cd850ed..dba0d8d 100644 (file)
@@ -1220,7 +1220,7 @@ void __init at91_set_serial_console(unsigned portnr)
 {
        if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
-               at91cap9_set_console_clock(portnr);
+               at91cap9_set_console_clock(at91_uarts[portnr]->id);
        }
 }
 
index b228ce9..83a1a3f 100644 (file)
@@ -199,9 +199,9 @@ static struct clk_lookup periph_clocks_lookups[] = {
        CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk),
        CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
        CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
-       CLKDEV_CON_DEV_ID("ssc", "ssc.0", &ssc0_clk),
-       CLKDEV_CON_DEV_ID("ssc", "ssc.1", &ssc1_clk),
-       CLKDEV_CON_DEV_ID("ssc", "ssc.2", &ssc2_clk),
+       CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+       CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+       CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
 };
 
 static struct clk_lookup usart_clocks_lookups[] = {
index a0ba475..7227755 100644 (file)
@@ -1135,7 +1135,7 @@ void __init at91_set_serial_console(unsigned portnr)
 {
        if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
-               at91rm9200_set_console_clock(portnr);
+               at91rm9200_set_console_clock(at91_uarts[portnr]->id);
        }
 }
 
index 1fdeb90..39f81f4 100644 (file)
@@ -1173,7 +1173,7 @@ void __init at91_set_serial_console(unsigned portnr)
 {
        if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
-               at91sam9260_set_console_clock(portnr);
+               at91sam9260_set_console_clock(at91_uarts[portnr]->id);
        }
 }
 
index 3eb4538..5004bf0 100644 (file)
@@ -1013,7 +1013,7 @@ void __init at91_set_serial_console(unsigned portnr)
 {
        if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
-               at91sam9261_set_console_clock(portnr);
+               at91sam9261_set_console_clock(at91_uarts[portnr]->id);
        }
 }
 
index ffe081b..a050f41 100644 (file)
@@ -1395,7 +1395,7 @@ void __init at91_set_serial_console(unsigned portnr)
 {
        if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
-               at91sam9263_set_console_clock(portnr);
+               at91sam9263_set_console_clock(at91_uarts[portnr]->id);
        }
 }
 
index 2bb6ff9..11e2141 100644 (file)
@@ -217,11 +217,11 @@ static struct clk *periph_clocks[] __initdata = {
 static struct clk_lookup periph_clocks_lookups[] = {
        /* One additional fake clock for ohci */
        CLKDEV_CON_ID("ohci_clk", &uhphs_clk),
-       CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci.0", &uhphs_clk),
-       CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc.0", &utmi_clk),
-       CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc.0", &udphs_clk),
-       CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
-       CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
+       CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk),
+       CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+       CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
+       CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk),
+       CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk),
        CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
        CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
        CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk),
index 0567486..600bffb 100644 (file)
@@ -1550,7 +1550,7 @@ void __init at91_set_serial_console(unsigned portnr)
 {
        if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
-               at91sam9g45_set_console_clock(portnr);
+               at91sam9g45_set_console_clock(at91_uarts[portnr]->id);
        }
 }
 
index 1a40f16..29dff18 100644 (file)
@@ -191,8 +191,8 @@ static struct clk *periph_clocks[] __initdata = {
 };
 
 static struct clk_lookup periph_clocks_lookups[] = {
-       CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc.0", &utmi_clk),
-       CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc.0", &udphs_clk),
+       CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+       CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
        CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
        CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
        CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
index c296045..aacb19d 100644 (file)
@@ -1168,7 +1168,7 @@ void __init at91_set_serial_console(unsigned portnr)
 {
        if (portnr < ATMEL_MAX_UART) {
                atmel_default_console_device = at91_uarts[portnr];
-               at91sam9rl_set_console_clock(portnr);
+               at91sam9rl_set_console_clock(at91_uarts[portnr]->id);
        }
 }
 
index 1904fdf..cdb65d4 100644 (file)
@@ -215,7 +215,7 @@ static void __init cap9adk_add_device_nand(void)
        csa = at91_sys_read(AT91_MATRIX_EBICSA);
        at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
 
-       cap9adk_nand_data.bus_width_16 = !board_have_nand_8bit();
+       cap9adk_nand_data.bus_width_16 = board_have_nand_16bit();
        /* setup bus-width (8 or 16) */
        if (cap9adk_nand_data.bus_width_16)
                cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16;
index d600dc1..5c24074 100644 (file)
@@ -214,7 +214,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
 
 static void __init ek_add_device_nand(void)
 {
-       ek_nand_data.bus_width_16 = !board_have_nand_8bit();
+       ek_nand_data.bus_width_16 = board_have_nand_16bit();
        /* setup bus-width (8 or 16) */
        if (ek_nand_data.bus_width_16)
                ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
index f897f84..b60c22b 100644 (file)
@@ -220,7 +220,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
 
 static void __init ek_add_device_nand(void)
 {
-       ek_nand_data.bus_width_16 = !board_have_nand_8bit();
+       ek_nand_data.bus_width_16 = board_have_nand_16bit();
        /* setup bus-width (8 or 16) */
        if (ek_nand_data.bus_width_16)
                ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
index 605b26f..9bbdc92 100644 (file)
@@ -221,7 +221,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
 
 static void __init ek_add_device_nand(void)
 {
-       ek_nand_data.bus_width_16 = !board_have_nand_8bit();
+       ek_nand_data.bus_width_16 = board_have_nand_16bit();
        /* setup bus-width (8 or 16) */
        if (ek_nand_data.bus_width_16)
                ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
index 7624cf0..1325a50 100644 (file)
@@ -198,7 +198,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
 
 static void __init ek_add_device_nand(void)
 {
-       ek_nand_data.bus_width_16 = !board_have_nand_8bit();
+       ek_nand_data.bus_width_16 = board_have_nand_16bit();
        /* setup bus-width (8 or 16) */
        if (ek_nand_data.bus_width_16)
                ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
index 063c95d..33eaa13 100644 (file)
@@ -178,7 +178,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
 
 static void __init ek_add_device_nand(void)
 {
-       ek_nand_data.bus_width_16 = !board_have_nand_8bit();
+       ek_nand_data.bus_width_16 = board_have_nand_16bit();
        /* setup bus-width (8 or 16) */
        if (ek_nand_data.bus_width_16)
                ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
index b855ee7..8f48660 100644 (file)
  * the 16-31 bit are reserved for at91 generic information
  *
  * bit 31:
- *     0 => nand 16 bit
- *     1 => nand 8 bit
+ *     0 => nand 8 bit
+ *     1 => nand 16 bit
  */
-#define BOARD_HAVE_NAND_8BIT   (1 << 31)
-static int inline board_have_nand_8bit(void)
+#define BOARD_HAVE_NAND_16BIT  (1 << 31)
+static inline int board_have_nand_16bit(void)
 {
-       return system_rev & BOARD_HAVE_NAND_8BIT;
+       return system_rev & BOARD_HAVE_NAND_16BIT;
 }
 
 #endif /* __ARCH_SYSTEM_REV_H__ */
index cf97500..68894fd 100644 (file)
@@ -112,8 +112,10 @@ static void nmi_cpu_start(void *dummy)
 static int nmi_start(void)
 {
        get_online_cpus();
-       on_each_cpu(nmi_cpu_start, NULL, 1);
        ctr_running = 1;
+       /* make ctr_running visible to the nmi handler: */
+       smp_mb();
+       on_each_cpu(nmi_cpu_start, NULL, 1);
        put_online_cpus();
        return 0;
 }
@@ -504,15 +506,18 @@ static int nmi_setup(void)
 
        nmi_enabled = 0;
        ctr_running = 0;
-       barrier();
+       /* make variables visible to the nmi handler: */
+       smp_mb();
        err = register_die_notifier(&profile_exceptions_nb);
        if (err)
                goto fail;
 
        get_online_cpus();
        register_cpu_notifier(&oprofile_cpu_nb);
-       on_each_cpu(nmi_cpu_setup, NULL, 1);
        nmi_enabled = 1;
+       /* make nmi_enabled visible to the nmi handler: */
+       smp_mb();
+       on_each_cpu(nmi_cpu_setup, NULL, 1);
        put_online_cpus();
 
        return 0;
@@ -531,7 +536,8 @@ static void nmi_shutdown(void)
        nmi_enabled = 0;
        ctr_running = 0;
        put_online_cpus();
-       barrier();
+       /* make variables visible to the nmi handler: */
+       smp_mb();
        unregister_die_notifier(&profile_exceptions_nb);
        msrs = &get_cpu_var(cpu_msrs);
        model->shutdown(msrs);
index 8214724..fe00830 100644 (file)
@@ -333,6 +333,7 @@ static int xen_register_pirq(u32 gsi, int triggering)
        struct physdev_map_pirq map_irq;
        int shareable = 0;
        char *name;
+       bool gsi_override = false;
 
        if (!xen_pv_domain())
                return -1;
@@ -349,11 +350,32 @@ static int xen_register_pirq(u32 gsi, int triggering)
        if (pirq < 0)
                goto out;
 
-       irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
+       /* Before we bind the GSI to a Linux IRQ, check whether
+        * we need to override it with bus_irq (IRQ) value. Usually for
+        * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so:
+        *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
+        * but there are oddballs where the IRQ != GSI:
+        *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level)
+        * which ends up being: gsi_to_irq[9] == 20
+        * (which is what acpi_gsi_to_irq ends up calling when starting the
+        * the ACPI interpreter and keels over since IRQ 9 has not been
+        * setup as we had setup IRQ 20 for it).
+        */
+       if (gsi == acpi_sci_override_gsi) {
+               /* Check whether the GSI != IRQ */
+               acpi_gsi_to_irq(gsi, &irq);
+               if (irq != gsi)
+                       /* Bugger, we MUST have that IRQ. */
+                       gsi_override = true;
+       }
+       if (gsi_override)
+               irq = xen_bind_pirq_gsi_to_irq(irq, pirq, shareable, name);
+       else
+               irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
        if (irq < 0)
                goto out;
 
-       printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d\n", pirq, irq);
+       printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi);
 
        map_irq.domid = DOMID_SELF;
        map_irq.type = MAP_PIRQ_TYPE_GSI;
index 673e968..0ccccb6 100644 (file)
@@ -1232,7 +1232,11 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
 {
        struct {
                struct mmuext_op op;
+#ifdef CONFIG_SMP
                DECLARE_BITMAP(mask, num_processors);
+#else
+               DECLARE_BITMAP(mask, NR_CPUS);
+#endif
        } *args;
        struct multicall_space mcs;
 
index 8d1ddfd..15097ca 100644 (file)
@@ -81,8 +81,10 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
        switch(tps65910_chip_id(tps65910)) {
        case TPS65910:
                tps65910->gpio.ngpio    = 6;
+               break;
        case TPS65911:
                tps65910->gpio.ngpio    = 9;
+               break;
        default:
                return;
        }
index 4d46441..0a893f7 100644 (file)
@@ -1207,13 +1207,17 @@ static int i915_context_status(struct seq_file *m, void *unused)
        if (ret)
                return ret;
 
-       seq_printf(m, "power context ");
-       describe_obj(m, dev_priv->pwrctx);
-       seq_printf(m, "\n");
+       if (dev_priv->pwrctx) {
+               seq_printf(m, "power context ");
+               describe_obj(m, dev_priv->pwrctx);
+               seq_printf(m, "\n");
+       }
 
-       seq_printf(m, "render context ");
-       describe_obj(m, dev_priv->renderctx);
-       seq_printf(m, "\n");
+       if (dev_priv->renderctx) {
+               seq_printf(m, "render context ");
+               describe_obj(m, dev_priv->renderctx);
+               seq_printf(m, "\n");
+       }
 
        mutex_unlock(&dev->mode_config.mutex);
 
index 2b79588..e178702 100644 (file)
@@ -1266,30 +1266,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
 
        intel_modeset_gem_init(dev);
 
-       if (IS_IVYBRIDGE(dev)) {
-               /* Share pre & uninstall handlers with ILK/SNB */
-               dev->driver->irq_handler = ivybridge_irq_handler;
-               dev->driver->irq_preinstall = ironlake_irq_preinstall;
-               dev->driver->irq_postinstall = ivybridge_irq_postinstall;
-               dev->driver->irq_uninstall = ironlake_irq_uninstall;
-               dev->driver->enable_vblank = ivybridge_enable_vblank;
-               dev->driver->disable_vblank = ivybridge_disable_vblank;
-       } else if (HAS_PCH_SPLIT(dev)) {
-               dev->driver->irq_handler = ironlake_irq_handler;
-               dev->driver->irq_preinstall = ironlake_irq_preinstall;
-               dev->driver->irq_postinstall = ironlake_irq_postinstall;
-               dev->driver->irq_uninstall = ironlake_irq_uninstall;
-               dev->driver->enable_vblank = ironlake_enable_vblank;
-               dev->driver->disable_vblank = ironlake_disable_vblank;
-       } else {
-               dev->driver->irq_preinstall = i915_driver_irq_preinstall;
-               dev->driver->irq_postinstall = i915_driver_irq_postinstall;
-               dev->driver->irq_uninstall = i915_driver_irq_uninstall;
-               dev->driver->irq_handler = i915_driver_irq_handler;
-               dev->driver->enable_vblank = i915_enable_vblank;
-               dev->driver->disable_vblank = i915_disable_vblank;
-       }
-
        ret = drm_irq_install(dev);
        if (ret)
                goto cleanup_gem;
@@ -2017,12 +1993,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        /* enable GEM by default */
        dev_priv->has_gem = 1;
 
-       dev->driver->get_vblank_counter = i915_get_vblank_counter;
-       dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-       if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
-               dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
-               dev->driver->get_vblank_counter = gm45_get_vblank_counter;
-       }
+       intel_irq_init(dev);
 
        /* Try to make sure MCHBAR is enabled before poking at it */
        intel_setup_mchbar(dev);
index 609358f..013d304 100644 (file)
@@ -765,14 +765,6 @@ static struct drm_driver driver = {
        .resume = i915_resume,
 
        .device_is_agp = i915_driver_device_is_agp,
-       .enable_vblank = i915_enable_vblank,
-       .disable_vblank = i915_disable_vblank,
-       .get_vblank_timestamp = i915_get_vblank_timestamp,
-       .get_scanout_position = i915_get_crtc_scanoutpos,
-       .irq_preinstall = i915_driver_irq_preinstall,
-       .irq_postinstall = i915_driver_irq_postinstall,
-       .irq_uninstall = i915_driver_irq_uninstall,
-       .irq_handler = i915_driver_irq_handler,
        .reclaim_buffers = drm_core_reclaim_buffers,
        .master_create = i915_master_create,
        .master_destroy = i915_master_destroy,
index eddabf6..f245c58 100644 (file)
@@ -997,8 +997,6 @@ extern unsigned int i915_enable_fbc;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
-extern void i915_save_display(struct drm_device *dev);
-extern void i915_restore_display(struct drm_device *dev);
 extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
 extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
 
@@ -1033,33 +1031,12 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
 extern int i915_irq_wait(struct drm_device *dev, void *data,
                         struct drm_file *file_priv);
 
-extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
-extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern int i915_driver_irq_postinstall(struct drm_device *dev);
-extern void i915_driver_irq_uninstall(struct drm_device * dev);
-
-extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS);
-extern void ironlake_irq_preinstall(struct drm_device *dev);
-extern int ironlake_irq_postinstall(struct drm_device *dev);
-extern void ironlake_irq_uninstall(struct drm_device *dev);
-
-extern irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS);
-extern void ivybridge_irq_preinstall(struct drm_device *dev);
-extern int ivybridge_irq_postinstall(struct drm_device *dev);
-extern void ivybridge_irq_uninstall(struct drm_device *dev);
+extern void intel_irq_init(struct drm_device *dev);
 
 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
-extern int i915_enable_vblank(struct drm_device *dev, int crtc);
-extern void i915_disable_vblank(struct drm_device *dev, int crtc);
-extern int ironlake_enable_vblank(struct drm_device *dev, int crtc);
-extern void ironlake_disable_vblank(struct drm_device *dev, int crtc);
-extern int ivybridge_enable_vblank(struct drm_device *dev, int crtc);
-extern void ivybridge_disable_vblank(struct drm_device *dev, int crtc);
-extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
-extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
 extern int i915_vblank_swap(struct drm_device *dev, void *data,
                            struct drm_file *file_priv);
 
@@ -1070,13 +1047,6 @@ void
 i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
 
 void intel_enable_asle (struct drm_device *dev);
-int i915_get_vblank_timestamp(struct drm_device *dev, int crtc,
-                             int *max_error,
-                             struct timeval *vblank_time,
-                             unsigned flags);
-
-int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
-                            int *vpos, int *hpos);
 
 #ifdef CONFIG_DEBUG_FS
 extern void i915_destroy_error_state(struct drm_device *dev);
index ae2b499..3b03f85 100644 (file)
@@ -152,7 +152,7 @@ i915_pipe_enabled(struct drm_device *dev, int pipe)
 /* Called from drm generic code, passed a 'crtc', which
  * we use as a pipe index
  */
-u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
+static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long high_frame;
@@ -184,7 +184,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
        return (high1 << 8) | low;
 }
 
-u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
+static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int reg = PIPE_FRMCOUNT_GM45(pipe);
@@ -198,7 +198,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
        return I915_READ(reg);
 }
 
-int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
+static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
                             int *vpos, int *hpos)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -264,7 +264,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
        return ret;
 }
 
-int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
+static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
                              int *max_error,
                              struct timeval *vblank_time,
                              unsigned flags)
@@ -462,7 +462,7 @@ static void pch_irq_handler(struct drm_device *dev)
                DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
 }
 
-irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
+static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -550,7 +550,7 @@ done:
        return ret;
 }
 
-irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
+static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1209,7 +1209,7 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
        }
 }
 
-irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
+static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1454,7 +1454,7 @@ int i915_irq_wait(struct drm_device *dev, void *data,
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
-int i915_enable_vblank(struct drm_device *dev, int pipe)
+static int i915_enable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
@@ -1478,7 +1478,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
        return 0;
 }
 
-int ironlake_enable_vblank(struct drm_device *dev, int pipe)
+static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
@@ -1494,7 +1494,7 @@ int ironlake_enable_vblank(struct drm_device *dev, int pipe)
        return 0;
 }
 
-int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
+static int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
@@ -1513,7 +1513,7 @@ int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
-void i915_disable_vblank(struct drm_device *dev, int pipe)
+static void i915_disable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
@@ -1529,7 +1529,7 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }
 
-void ironlake_disable_vblank(struct drm_device *dev, int pipe)
+static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
@@ -1540,7 +1540,7 @@ void ironlake_disable_vblank(struct drm_device *dev, int pipe)
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }
 
-void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
+static void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        unsigned long irqflags;
@@ -1728,7 +1728,7 @@ repeat:
 
 /* drm_dma.h hooks
 */
-void ironlake_irq_preinstall(struct drm_device *dev)
+static void ironlake_irq_preinstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
@@ -1740,7 +1740,7 @@ void ironlake_irq_preinstall(struct drm_device *dev)
                INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
 
        I915_WRITE(HWSTAM, 0xeffe);
-       if (IS_GEN6(dev)) {
+       if (IS_GEN6(dev) || IS_GEN7(dev)) {
                /* Workaround stalls observed on Sandy Bridge GPUs by
                 * making the blitter command streamer generate a
                 * write to the Hardware Status Page for
@@ -1769,7 +1769,7 @@ void ironlake_irq_preinstall(struct drm_device *dev)
        POSTING_READ(SDEIER);
 }
 
-int ironlake_irq_postinstall(struct drm_device *dev)
+static int ironlake_irq_postinstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        /* enable kind of interrupts always enabled */
@@ -1841,7 +1841,7 @@ int ironlake_irq_postinstall(struct drm_device *dev)
        return 0;
 }
 
-int ivybridge_irq_postinstall(struct drm_device *dev)
+static int ivybridge_irq_postinstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        /* enable kind of interrupts always enabled */
@@ -1891,7 +1891,7 @@ int ivybridge_irq_postinstall(struct drm_device *dev)
        return 0;
 }
 
-void i915_driver_irq_preinstall(struct drm_device * dev)
+static void i915_driver_irq_preinstall(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int pipe;
@@ -1918,7 +1918,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
  * Must be called after intel_modeset_init or hotplug interrupts won't be
  * enabled correctly.
  */
-int i915_driver_irq_postinstall(struct drm_device *dev)
+static int i915_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
@@ -1994,7 +1994,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
        return 0;
 }
 
-void ironlake_irq_uninstall(struct drm_device *dev)
+static void ironlake_irq_uninstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
@@ -2014,7 +2014,7 @@ void ironlake_irq_uninstall(struct drm_device *dev)
        I915_WRITE(GTIIR, I915_READ(GTIIR));
 }
 
-void i915_driver_irq_uninstall(struct drm_device * dev)
+static void i915_driver_irq_uninstall(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int pipe;
@@ -2040,3 +2040,41 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
                           I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
        I915_WRITE(IIR, I915_READ(IIR));
 }
+
+void intel_irq_init(struct drm_device *dev)
+{
+       dev->driver->get_vblank_counter = i915_get_vblank_counter;
+       dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+       if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
+               dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
+               dev->driver->get_vblank_counter = gm45_get_vblank_counter;
+       }
+
+
+       dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
+       dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
+
+       if (IS_IVYBRIDGE(dev)) {
+               /* Share pre & uninstall handlers with ILK/SNB */
+               dev->driver->irq_handler = ivybridge_irq_handler;
+               dev->driver->irq_preinstall = ironlake_irq_preinstall;
+               dev->driver->irq_postinstall = ivybridge_irq_postinstall;
+               dev->driver->irq_uninstall = ironlake_irq_uninstall;
+               dev->driver->enable_vblank = ivybridge_enable_vblank;
+               dev->driver->disable_vblank = ivybridge_disable_vblank;
+       } else if (HAS_PCH_SPLIT(dev)) {
+               dev->driver->irq_handler = ironlake_irq_handler;
+               dev->driver->irq_preinstall = ironlake_irq_preinstall;
+               dev->driver->irq_postinstall = ironlake_irq_postinstall;
+               dev->driver->irq_uninstall = ironlake_irq_uninstall;
+               dev->driver->enable_vblank = ironlake_enable_vblank;
+               dev->driver->disable_vblank = ironlake_disable_vblank;
+       } else {
+               dev->driver->irq_preinstall = i915_driver_irq_preinstall;
+               dev->driver->irq_postinstall = i915_driver_irq_postinstall;
+               dev->driver->irq_uninstall = i915_driver_irq_uninstall;
+               dev->driver->irq_handler = i915_driver_irq_handler;
+               dev->driver->enable_vblank = i915_enable_vblank;
+               dev->driver->disable_vblank = i915_disable_vblank;
+       }
+}
index e8152d2..5257cfc 100644 (file)
@@ -597,7 +597,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
        return;
 }
 
-void i915_save_display(struct drm_device *dev)
+static void i915_save_display(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -678,7 +678,6 @@ void i915_save_display(struct drm_device *dev)
        }
 
        /* VGA state */
-       mutex_lock(&dev->struct_mutex);
        dev_priv->saveVGA0 = I915_READ(VGA0);
        dev_priv->saveVGA1 = I915_READ(VGA1);
        dev_priv->saveVGA_PD = I915_READ(VGA_PD);
@@ -688,10 +687,9 @@ void i915_save_display(struct drm_device *dev)
                dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
 
        i915_save_vga(dev);
-       mutex_unlock(&dev->struct_mutex);
 }
 
-void i915_restore_display(struct drm_device *dev)
+static void i915_restore_display(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -783,7 +781,6 @@ void i915_restore_display(struct drm_device *dev)
        else
                I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
 
-       mutex_lock(&dev->struct_mutex);
        I915_WRITE(VGA0, dev_priv->saveVGA0);
        I915_WRITE(VGA1, dev_priv->saveVGA1);
        I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
@@ -791,7 +788,6 @@ void i915_restore_display(struct drm_device *dev)
        udelay(150);
 
        i915_restore_vga(dev);
-       mutex_unlock(&dev->struct_mutex);
 }
 
 int i915_save_state(struct drm_device *dev)
@@ -801,6 +797,8 @@ int i915_save_state(struct drm_device *dev)
 
        pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
 
+       mutex_lock(&dev->struct_mutex);
+
        /* Hardware status page */
        dev_priv->saveHWS = I915_READ(HWS_PGA);
 
@@ -840,6 +838,8 @@ int i915_save_state(struct drm_device *dev)
        for (i = 0; i < 3; i++)
                dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
 
+       mutex_unlock(&dev->struct_mutex);
+
        return 0;
 }
 
@@ -850,6 +850,8 @@ int i915_restore_state(struct drm_device *dev)
 
        pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
 
+       mutex_lock(&dev->struct_mutex);
+
        /* Hardware status page */
        I915_WRITE(HWS_PGA, dev_priv->saveHWS);
 
@@ -867,6 +869,7 @@ int i915_restore_state(struct drm_device *dev)
                I915_WRITE(IER, dev_priv->saveIER);
                I915_WRITE(IMR, dev_priv->saveIMR);
        }
+       mutex_unlock(&dev->struct_mutex);
 
        intel_init_clock_gating(dev);
 
@@ -878,6 +881,8 @@ int i915_restore_state(struct drm_device *dev)
        if (IS_GEN6(dev))
                gen6_enable_rps(dev_priv);
 
+       mutex_lock(&dev->struct_mutex);
+
        /* Cache mode state */
        I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
 
@@ -891,6 +896,8 @@ int i915_restore_state(struct drm_device *dev)
        for (i = 0; i < 3; i++)
                I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
 
+       mutex_unlock(&dev->struct_mutex);
+
        intel_i2c_reset(dev);
 
        return 0;
index 56a8e2a..9e2959b 100644 (file)
@@ -1409,6 +1409,11 @@ void intel_setup_overlay(struct drm_device *dev)
        overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
        if (!overlay)
                return;
+
+       mutex_lock(&dev->struct_mutex);
+       if (WARN_ON(dev_priv->overlay))
+               goto out_free;
+
        overlay->dev = dev;
 
        reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
@@ -1416,8 +1421,6 @@ void intel_setup_overlay(struct drm_device *dev)
                goto out_free;
        overlay->reg_bo = reg_bo;
 
-       mutex_lock(&dev->struct_mutex);
-
        if (OVERLAY_NEEDS_PHYSICAL(dev)) {
                ret = i915_gem_attach_phys_object(dev, reg_bo,
                                                  I915_GEM_PHYS_OVERLAY_REGS,
@@ -1442,8 +1445,6 @@ void intel_setup_overlay(struct drm_device *dev)
                 }
        }
 
-       mutex_unlock(&dev->struct_mutex);
-
        /* init all values */
        overlay->color_key = 0x0101fe;
        overlay->brightness = -19;
@@ -1452,7 +1453,7 @@ void intel_setup_overlay(struct drm_device *dev)
 
        regs = intel_overlay_map_regs(overlay);
        if (!regs)
-               goto out_free_bo;
+               goto out_unpin_bo;
 
        memset(regs, 0, sizeof(struct overlay_registers));
        update_polyphase_filter(regs);
@@ -1461,15 +1462,17 @@ void intel_setup_overlay(struct drm_device *dev)
        intel_overlay_unmap_regs(overlay, regs);
 
        dev_priv->overlay = overlay;
+       mutex_unlock(&dev->struct_mutex);
        DRM_INFO("initialized overlay support\n");
        return;
 
 out_unpin_bo:
-       i915_gem_object_unpin(reg_bo);
+       if (!OVERLAY_NEEDS_PHYSICAL(dev))
+               i915_gem_object_unpin(reg_bo);
 out_free_bo:
        drm_gem_object_unreference(&reg_bo->base);
-       mutex_unlock(&dev->struct_mutex);
 out_free:
+       mutex_unlock(&dev->struct_mutex);
        kfree(overlay);
        return;
 }
index 144f79a..731acea 100644 (file)
@@ -371,7 +371,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->vram.flags_valid        = nv50_vram_flags_valid;
                break;
        case 0xC0:
-       case 0xD0:
                engine->instmem.init            = nvc0_instmem_init;
                engine->instmem.takedown        = nvc0_instmem_takedown;
                engine->instmem.suspend         = nvc0_instmem_suspend;
@@ -923,7 +922,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
                dev_priv->card_type = NV_50;
                break;
        case 0xc0:
-       case 0xd0:
                dev_priv->card_type = NV_C0;
                break;
        default:
index 12d2fdc..e8a5ffb 100644 (file)
@@ -2248,7 +2248,10 @@ int evergreen_mc_init(struct radeon_device *rdev)
 
        /* Get VRAM informations */
        rdev->mc.vram_is_ddr = true;
-       tmp = RREG32(MC_ARB_RAMCFG);
+       if (rdev->flags & RADEON_IS_IGP)
+               tmp = RREG32(FUS_MC_ARB_RAMCFG);
+       else
+               tmp = RREG32(MC_ARB_RAMCFG);
        if (tmp & CHANSIZE_OVERRIDE) {
                chansize = 16;
        } else if (tmp & CHANSIZE_MASK) {
index 9736746..4672869 100644 (file)
 #define        CGTS_USER_TCC_DISABLE                           0x914C
 #define                TCC_DISABLE_MASK                                0xFFFF0000
 #define                TCC_DISABLE_SHIFT                               16
-#define        CGTS_SM_CTRL_REG                                0x915C
+#define        CGTS_SM_CTRL_REG                                0x9150
 #define                OVERRIDE                                (1 << 21)
 
 #define        TA_CNTL_AUX                                     0x9508
index 16db83c..5f888f7 100644 (file)
@@ -333,7 +333,7 @@ config SENSORS_F71882FG
            F71858FG
            F71862FG
            F71863FG
-           F71869F/E
+           F71869F/E/A
            F71882FG
            F71883FG
            F71889FG/ED/A
index c2ee204..b9b7caf 100644 (file)
@@ -32,6 +32,7 @@ static int adm1275_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
        int config;
+       int ret;
        struct pmbus_driver_info *info;
 
        if (!i2c_check_functionality(client->adapter,
@@ -43,8 +44,10 @@ static int adm1275_probe(struct i2c_client *client,
                return -ENOMEM;
 
        config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
-       if (config < 0)
-               return config;
+       if (config < 0) {
+               ret = config;
+               goto err_mem;
+       }
 
        info->pages = 1;
        info->direct[PSC_VOLTAGE_IN] = true;
@@ -76,7 +79,14 @@ static int adm1275_probe(struct i2c_client *client,
        else
                info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
 
-       return pmbus_do_probe(client, id, info);
+       ret = pmbus_do_probe(client, id, info);
+       if (ret)
+               goto err_mem;
+       return 0;
+
+err_mem:
+       kfree(info);
+       return ret;
 }
 
 static int adm1275_remove(struct i2c_client *client)
index e0ef323..0064432 100644 (file)
@@ -78,8 +78,9 @@ static u16 emc6w201_read16(struct i2c_client *client, u8 reg)
 
        lsb = i2c_smbus_read_byte_data(client, reg);
        msb = i2c_smbus_read_byte_data(client, reg + 1);
-       if (lsb < 0 || msb < 0) {
-               dev_err(&client->dev, "16-bit read failed at 0x%02x\n", reg);
+       if (unlikely(lsb < 0 || msb < 0)) {
+               dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+                       16, "read", reg);
                return 0xFFFF;  /* Arbitrary value */
        }
 
@@ -95,10 +96,39 @@ static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val)
        int err;
 
        err = i2c_smbus_write_byte_data(client, reg, val & 0xff);
-       if (!err)
+       if (likely(!err))
                err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8);
-       if (err < 0)
-               dev_err(&client->dev, "16-bit write failed at 0x%02x\n", reg);
+       if (unlikely(err < 0))
+               dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+                       16, "write", reg);
+
+       return err;
+}
+
+/* Read 8-bit value from register */
+static u8 emc6w201_read8(struct i2c_client *client, u8 reg)
+{
+       int val;
+
+       val = i2c_smbus_read_byte_data(client, reg);
+       if (unlikely(val < 0)) {
+               dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+                       8, "read", reg);
+               return 0x00;    /* Arbitrary value */
+       }
+
+       return val;
+}
+
+/* Write 8-bit value to register */
+static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)
+{
+       int err;
+
+       err = i2c_smbus_write_byte_data(client, reg, val);
+       if (unlikely(err < 0))
+               dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+                       8, "write", reg);
 
        return err;
 }
@@ -114,25 +144,25 @@ static struct emc6w201_data *emc6w201_update_device(struct device *dev)
        if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
                for (nr = 0; nr < 6; nr++) {
                        data->in[input][nr] =
-                               i2c_smbus_read_byte_data(client,
+                               emc6w201_read8(client,
                                                EMC6W201_REG_IN(nr));
                        data->in[min][nr] =
-                               i2c_smbus_read_byte_data(client,
+                               emc6w201_read8(client,
                                                EMC6W201_REG_IN_LOW(nr));
                        data->in[max][nr] =
-                               i2c_smbus_read_byte_data(client,
+                               emc6w201_read8(client,
                                                EMC6W201_REG_IN_HIGH(nr));
                }
 
                for (nr = 0; nr < 6; nr++) {
                        data->temp[input][nr] =
-                               i2c_smbus_read_byte_data(client,
+                               emc6w201_read8(client,
                                                EMC6W201_REG_TEMP(nr));
                        data->temp[min][nr] =
-                               i2c_smbus_read_byte_data(client,
+                               emc6w201_read8(client,
                                                EMC6W201_REG_TEMP_LOW(nr));
                        data->temp[max][nr] =
-                               i2c_smbus_read_byte_data(client,
+                               emc6w201_read8(client,
                                                EMC6W201_REG_TEMP_HIGH(nr));
                }
 
@@ -192,7 +222,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
 
        mutex_lock(&data->update_lock);
        data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255);
-       err = i2c_smbus_write_byte_data(client, reg, data->in[sf][nr]);
+       err = emc6w201_write8(client, reg, data->in[sf][nr]);
        mutex_unlock(&data->update_lock);
 
        return err < 0 ? err : count;
@@ -229,7 +259,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 
        mutex_lock(&data->update_lock);
        data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128);
-       err = i2c_smbus_write_byte_data(client, reg, data->temp[sf][nr]);
+       err = emc6w201_write8(client, reg, data->temp[sf][nr]);
        mutex_unlock(&data->update_lock);
 
        return err < 0 ? err : count;
@@ -444,7 +474,7 @@ static int emc6w201_detect(struct i2c_client *client,
 
        /* Check configuration */
        config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG);
-       if ((config & 0xF4) != 0x04)
+       if (config < 0 || (config & 0xF4) != 0x04)
                return -ENODEV;
        if (!(config & 0x01)) {
                dev_err(&client->dev, "Monitoring not enabled\n");
index a4a94a0..2d96ed2 100644 (file)
@@ -52,6 +52,7 @@
 #define SIO_F71858_ID          0x0507  /* Chipset ID */
 #define SIO_F71862_ID          0x0601  /* Chipset ID */
 #define SIO_F71869_ID          0x0814  /* Chipset ID */
+#define SIO_F71869A_ID         0x1007  /* Chipset ID */
 #define SIO_F71882_ID          0x0541  /* Chipset ID */
 #define SIO_F71889_ID          0x0723  /* Chipset ID */
 #define SIO_F71889E_ID         0x0909  /* Chipset ID */
@@ -108,8 +109,8 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
-            f71889ed, f71889a, f8000, f81865f };
+enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
+            f71889fg, f71889ed, f71889a, f8000, f81865f };
 
 static const char *f71882fg_names[] = {
        "f71808e",
@@ -117,6 +118,7 @@ static const char *f71882fg_names[] = {
        "f71858fg",
        "f71862fg",
        "f71869", /* Both f71869f and f71869e, reg. compatible and same id */
+       "f71869a",
        "f71882fg",
        "f71889fg", /* f81801u too, same id */
        "f71889ed",
@@ -131,6 +133,7 @@ static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
        [f71858fg]      = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
        [f71862fg]      = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        [f71869]        = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+       [f71869a]       = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        [f71882fg]      = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        [f71889fg]      = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        [f71889ed]      = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
@@ -145,6 +148,7 @@ static const char f71882fg_has_in1_alarm[] = {
        [f71858fg]      = 0,
        [f71862fg]      = 0,
        [f71869]        = 0,
+       [f71869a]       = 0,
        [f71882fg]      = 1,
        [f71889fg]      = 1,
        [f71889ed]      = 1,
@@ -159,6 +163,7 @@ static const char f71882fg_fan_has_beep[] = {
        [f71858fg]      = 0,
        [f71862fg]      = 1,
        [f71869]        = 1,
+       [f71869a]       = 1,
        [f71882fg]      = 1,
        [f71889fg]      = 1,
        [f71889ed]      = 1,
@@ -173,6 +178,7 @@ static const char f71882fg_nr_fans[] = {
        [f71858fg]      = 3,
        [f71862fg]      = 3,
        [f71869]        = 3,
+       [f71869a]       = 3,
        [f71882fg]      = 4,
        [f71889fg]      = 3,
        [f71889ed]      = 3,
@@ -187,6 +193,7 @@ static const char f71882fg_temp_has_beep[] = {
        [f71858fg]      = 0,
        [f71862fg]      = 1,
        [f71869]        = 1,
+       [f71869a]       = 1,
        [f71882fg]      = 1,
        [f71889fg]      = 1,
        [f71889ed]      = 1,
@@ -201,6 +208,7 @@ static const char f71882fg_nr_temps[] = {
        [f71858fg]      = 3,
        [f71862fg]      = 3,
        [f71869]        = 3,
+       [f71869a]       = 3,
        [f71882fg]      = 3,
        [f71889fg]      = 3,
        [f71889ed]      = 3,
@@ -2243,6 +2251,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
                case f71808e:
                case f71808a:
                case f71869:
+               case f71869a:
                        /* These always have signed auto point temps */
                        data->auto_point_temp_signed = 1;
                        /* Fall through to select correct fan/pwm reg bank! */
@@ -2305,6 +2314,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
                case f71808e:
                case f71808a:
                case f71869:
+               case f71869a:
                case f71889fg:
                case f71889ed:
                case f71889a:
@@ -2528,6 +2538,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
        case SIO_F71869_ID:
                sio_data->type = f71869;
                break;
+       case SIO_F71869A_ID:
+               sio_data->type = f71869a;
+               break;
        case SIO_F71882_ID:
                sio_data->type = f71882fg;
                break;
@@ -2662,7 +2675,7 @@ static void __exit f71882fg_exit(void)
 }
 
 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
 
 module_init(f71882fg_init);
index 2582bfe..c8195a0 100644 (file)
@@ -202,7 +202,7 @@ static struct vrm_model vrm_models[] = {
 
        {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85},        /* Eden ESP/Ezra */
        {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85},        /* Ezra T */
-       {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},        /* Nemiah */
+       {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},        /* Nehemiah */
        {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17},        /* C3-M, Eden-N */
        {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0},         /* No information */
        {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13},        /* C7, Esther */
index 98e2e28..931d940 100644 (file)
@@ -47,12 +47,14 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
        if (info->func[0]
            && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
                info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
-       if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
+       if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
+           pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
                info->func[0] |= PMBUS_HAVE_FAN12;
                if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
                        info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
        }
-       if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
+       if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
+           pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
                info->func[0] |= PMBUS_HAVE_FAN34;
                if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
                        info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
@@ -63,6 +65,10 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
                                              PMBUS_STATUS_TEMPERATURE))
                        info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
        }
+       if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
+               info->func[0] |= PMBUS_HAVE_TEMP2;
+       if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
+               info->func[0] |= PMBUS_HAVE_TEMP3;
 
        /* Sensors detected on all pages */
        for (page = 0; page < info->pages; page++) {
index 354770e..744672c 100644 (file)
@@ -1430,14 +1430,9 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
 
-       /*
-        * Bail out if status register or PMBus revision register
-        * does not exist.
-        */
-       if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0
-           || i2c_smbus_read_byte_data(client, PMBUS_REVISION) < 0) {
-               dev_err(&client->dev,
-                       "Status or revision register not found\n");
+       /* Bail out if PMBus status register does not exist. */
+       if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) {
+               dev_err(&client->dev, "PMBus status register not found\n");
                ret = -ENODEV;
                goto out_data;
        }
index 020c872..3494a4c 100644 (file)
@@ -887,7 +887,7 @@ static void __exit sch5627_exit(void)
 }
 
 MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
 
 module_init(sch5627_init);
index f62f52f..fc0f2bd 100644 (file)
@@ -3641,7 +3641,8 @@ static struct kobj_type cm_port_obj_type = {
 
 static char *cm_devnode(struct device *dev, mode_t *mode)
 {
-       *mode = 0666;
+       if (mode)
+               *mode = 0666;
        return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
 }
 
index e49a85f..56898b6 100644 (file)
@@ -826,7 +826,8 @@ static void ib_uverbs_remove_one(struct ib_device *device)
 
 static char *uverbs_devnode(struct device *dev, mode_t *mode)
 {
-       *mode = 0666;
+       if (mode)
+               *mode = 0666;
        return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
 }
 
index 40b02ae..6229c3e 100644 (file)
@@ -520,7 +520,8 @@ static void pmic8xxx_kp_close(struct input_dev *dev)
  */
 static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev)
 {
-       const struct pm8xxx_keypad_platform_data *pdata = mfd_get_data(pdev);
+       const struct pm8xxx_keypad_platform_data *pdata =
+                                       dev_get_platdata(&pdev->dev);
        const struct matrix_keymap_data *keymap_data;
        struct pmic8xxx_kp *kp;
        int rc;
index 97e07e7..b3cfb9c 100644 (file)
@@ -90,7 +90,8 @@ static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev)
        unsigned int delay;
        u8 pon_cntl;
        struct pmic8xxx_pwrkey *pwrkey;
-       const struct pm8xxx_pwrkey_platform_data *pdata = mfd_get_data(pdev);
+       const struct pm8xxx_pwrkey_platform_data *pdata =
+                                       dev_get_platdata(&pdev->dev);
 
        if (!pdata) {
                dev_err(&pdev->dev, "power key platform data not supplied\n");
index 8fa539d..7f7079b 100644 (file)
@@ -597,12 +597,17 @@ static void __devexit fintek_remove(struct pnp_dev *pdev)
 static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state)
 {
        struct fintek_dev *fintek = pnp_get_drvdata(pdev);
+       unsigned long flags;
 
        fit_dbg("%s called", __func__);
 
+       spin_lock_irqsave(&fintek->fintek_lock, flags);
+
        /* disable all CIR interrupts */
        fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
 
+       spin_unlock_irqrestore(&fintek->fintek_lock, flags);
+
        fintek_config_mode_enable(fintek);
 
        /* disable cir logical dev */
index 3f3c707..6bc35ee 100644 (file)
@@ -307,6 +307,14 @@ static const struct {
        /* 0xffdc iMON MCE VFD */
        { 0x00010000ffffffeell, KEY_VOLUMEUP },
        { 0x01000000ffffffeell, KEY_VOLUMEDOWN },
+       { 0x00000001ffffffeell, KEY_MUTE },
+       { 0x0000000fffffffeell, KEY_MEDIA },
+       { 0x00000012ffffffeell, KEY_UP },
+       { 0x00000013ffffffeell, KEY_DOWN },
+       { 0x00000014ffffffeell, KEY_LEFT },
+       { 0x00000015ffffffeell, KEY_RIGHT },
+       { 0x00000016ffffffeell, KEY_ENTER },
+       { 0x00000017ffffffeell, KEY_ESC },
        /* iMON Knob values */
        { 0x000100ffffffffeell, KEY_VOLUMEUP },
        { 0x010000ffffffffeell, KEY_VOLUMEDOWN },
@@ -1582,16 +1590,16 @@ static void imon_incoming_packet(struct imon_context *ictx,
        /* Only panel type events left to process now */
        spin_lock_irqsave(&ictx->kc_lock, flags);
 
+       do_gettimeofday(&t);
        /* KEY_MUTE repeats from knob need to be suppressed */
        if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
-               do_gettimeofday(&t);
                msec = tv2int(&t, &prev_time);
-               prev_time = t;
                if (msec < ictx->idev->rep[REP_DELAY]) {
                        spin_unlock_irqrestore(&ictx->kc_lock, flags);
                        return;
                }
        }
+       prev_time = t;
        kc = ictx->kc;
 
        spin_unlock_irqrestore(&ictx->kc_lock, flags);
@@ -1603,7 +1611,9 @@ static void imon_incoming_packet(struct imon_context *ictx,
        input_report_key(ictx->idev, kc, 0);
        input_sync(ictx->idev);
 
+       spin_lock_irqsave(&ictx->kc_lock, flags);
        ictx->last_keycode = kc;
+       spin_unlock_irqrestore(&ictx->kc_lock, flags);
 
        return;
 
@@ -1740,6 +1750,8 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
                break;
        /* iMON VFD, MCE IR */
+       case 0x46:
+       case 0x7e:
        case 0x9e:
                dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
@@ -1755,6 +1767,9 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
                dev_info(ictx->dev, "Unknown 0xffdc device, "
                         "defaulting to VFD and iMON IR");
                detected_display_type = IMON_DISPLAY_TYPE_VFD;
+               /* We don't know which one it is, allow user to set the
+                * RC6 one from userspace if OTHER wasn't correct. */
+               allowed_protos |= RC_TYPE_RC6;
                break;
        }
 
index 11c19d8..423ed45 100644 (file)
@@ -114,18 +114,20 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type)
        s64                     delta; /* ns */
        DEFINE_IR_RAW_EVENT(ev);
        int                     rc = 0;
+       int                     delay;
 
        if (!dev->raw)
                return -EINVAL;
 
        now = ktime_get();
        delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
+       delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]);
 
        /* Check for a long duration since last event or if we're
         * being called for the first time, note that delta can't
         * possibly be negative.
         */
-       if (delta > IR_MAX_DURATION || !dev->raw->last_type)
+       if (delta > delay || !dev->raw->last_type)
                type |= IR_START_EVENT;
        else
                ev.duration = delta;
index e716b93..ecd3d02 100644 (file)
@@ -1347,6 +1347,7 @@ static const struct ite_dev_params ite_dev_descs[] = {
        {       /* 0: ITE8704 */
               .model = "ITE8704 CIR transceiver",
               .io_region_size = IT87_IOREG_LENGTH,
+              .io_rsrc_no = 0,
               .hw_tx_capable = true,
               .sample_period = (u32) (1000000000ULL / 115200),
               .tx_carrier_freq = 38000,
@@ -1371,6 +1372,7 @@ static const struct ite_dev_params ite_dev_descs[] = {
        {       /* 1: ITE8713 */
               .model = "ITE8713 CIR transceiver",
               .io_region_size = IT87_IOREG_LENGTH,
+              .io_rsrc_no = 0,
               .hw_tx_capable = true,
               .sample_period = (u32) (1000000000ULL / 115200),
               .tx_carrier_freq = 38000,
@@ -1395,6 +1397,7 @@ static const struct ite_dev_params ite_dev_descs[] = {
        {       /* 2: ITE8708 */
               .model = "ITE8708 CIR transceiver",
               .io_region_size = IT8708_IOREG_LENGTH,
+              .io_rsrc_no = 0,
               .hw_tx_capable = true,
               .sample_period = (u32) (1000000000ULL / 115200),
               .tx_carrier_freq = 38000,
@@ -1420,6 +1423,7 @@ static const struct ite_dev_params ite_dev_descs[] = {
        {       /* 3: ITE8709 */
               .model = "ITE8709 CIR transceiver",
               .io_region_size = IT8709_IOREG_LENGTH,
+              .io_rsrc_no = 2,
               .hw_tx_capable = true,
               .sample_period = (u32) (1000000000ULL / 115200),
               .tx_carrier_freq = 38000,
@@ -1461,6 +1465,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
        struct rc_dev *rdev = NULL;
        int ret = -ENOMEM;
        int model_no;
+       int io_rsrc_no;
 
        ite_dbg("%s called", __func__);
 
@@ -1490,10 +1495,11 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
 
        /* get the description for the device */
        dev_desc = &ite_dev_descs[model_no];
+       io_rsrc_no = dev_desc->io_rsrc_no;
 
        /* validate pnp resources */
-       if (!pnp_port_valid(pdev, 0) ||
-           pnp_port_len(pdev, 0) != dev_desc->io_region_size) {
+       if (!pnp_port_valid(pdev, io_rsrc_no) ||
+           pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) {
                dev_err(&pdev->dev, "IR PNP Port not valid!\n");
                goto failure;
        }
@@ -1504,7 +1510,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
        }
 
        /* store resource values */
-       itdev->cir_addr = pnp_port_start(pdev, 0);
+       itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no);
        itdev->cir_irq = pnp_irq(pdev, 0);
 
        /* initialize spinlocks */
index 16a19f5..aa899a0 100644 (file)
@@ -57,6 +57,9 @@ struct ite_dev_params {
        /* size of the I/O region */
        int io_region_size;
 
+       /* IR pnp I/O resource number */
+       int io_rsrc_no;
+
        /* true if the hardware supports transmission */
        bool hw_tx_capable;
 
index bb10ffe..8d558ae 100644 (file)
 /* Pinnacle PCTV HD 800i mini remote */
 
 static struct rc_map_table pinnacle_pctv_hd[] = {
-
-       { 0x0f, KEY_1 },
-       { 0x15, KEY_2 },
-       { 0x10, KEY_3 },
-       { 0x18, KEY_4 },
-       { 0x1b, KEY_5 },
-       { 0x1e, KEY_6 },
-       { 0x11, KEY_7 },
-       { 0x21, KEY_8 },
-       { 0x12, KEY_9 },
-       { 0x27, KEY_0 },
-
-       { 0x24, KEY_ZOOM },
-       { 0x2a, KEY_SUBTITLE },
-
-       { 0x00, KEY_MUTE },
-       { 0x01, KEY_ENTER },    /* Pinnacle Logo */
-       { 0x39, KEY_POWER },
-
-       { 0x03, KEY_VOLUMEUP },
-       { 0x09, KEY_VOLUMEDOWN },
-       { 0x06, KEY_CHANNELUP },
-       { 0x0c, KEY_CHANNELDOWN },
-
-       { 0x2d, KEY_REWIND },
-       { 0x30, KEY_PLAYPAUSE },
-       { 0x33, KEY_FASTFORWARD },
-       { 0x3c, KEY_STOP },
-       { 0x36, KEY_RECORD },
-       { 0x3f, KEY_EPG },      /* Labeled "?" */
+       /* Key codes for the tiny Pinnacle remote*/
+       { 0x0700, KEY_MUTE },
+       { 0x0701, KEY_MENU }, /* Pinnacle logo */
+       { 0x0739, KEY_POWER },
+       { 0x0703, KEY_VOLUMEUP },
+       { 0x0709, KEY_VOLUMEDOWN },
+       { 0x0706, KEY_CHANNELUP },
+       { 0x070c, KEY_CHANNELDOWN },
+       { 0x070f, KEY_1 },
+       { 0x0715, KEY_2 },
+       { 0x0710, KEY_3 },
+       { 0x0718, KEY_4 },
+       { 0x071b, KEY_5 },
+       { 0x071e, KEY_6 },
+       { 0x0711, KEY_7 },
+       { 0x0721, KEY_8 },
+       { 0x0712, KEY_9 },
+       { 0x0727, KEY_0 },
+       { 0x0724, KEY_ZOOM }, /* 'Square' key */
+       { 0x072a, KEY_SUBTITLE },   /* 'T' key */
+       { 0x072d, KEY_REWIND },
+       { 0x0730, KEY_PLAYPAUSE },
+       { 0x0733, KEY_FASTFORWARD },
+       { 0x0736, KEY_RECORD },
+       { 0x073c, KEY_STOP },
+       { 0x073f, KEY_HELP }, /* '?' key */
 };
 
 static struct rc_map_list pinnacle_pctv_hd_map = {
        .map = {
                .scan    = pinnacle_pctv_hd,
                .size    = ARRAY_SIZE(pinnacle_pctv_hd),
-               .rc_type = RC_TYPE_UNKNOWN,     /* Legacy IR type */
+               .rc_type = RC_TYPE_RC5,
                .name    = RC_MAP_PINNACLE_PCTV_HD,
        }
 };
index fd237ab..27997a9 100644 (file)
@@ -55,6 +55,8 @@ struct irctl {
        struct lirc_buffer *buf;
        unsigned int chunk_size;
 
+       struct cdev *cdev;
+
        struct task_struct *task;
        long jiffies_to_wait;
 };
@@ -62,7 +64,6 @@ struct irctl {
 static DEFINE_MUTEX(lirc_dev_lock);
 
 static struct irctl *irctls[MAX_IRCTL_DEVICES];
-static struct cdev cdevs[MAX_IRCTL_DEVICES];
 
 /* Only used for sysfs but defined to void otherwise */
 static struct class *lirc_class;
@@ -167,9 +168,13 @@ static struct file_operations lirc_dev_fops = {
 
 static int lirc_cdev_add(struct irctl *ir)
 {
-       int retval;
+       int retval = -ENOMEM;
        struct lirc_driver *d = &ir->d;
-       struct cdev *cdev = &cdevs[d->minor];
+       struct cdev *cdev;
+
+       cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+       if (!cdev)
+               goto err_out;
 
        if (d->fops) {
                cdev_init(cdev, d->fops);
@@ -180,12 +185,20 @@ static int lirc_cdev_add(struct irctl *ir)
        }
        retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
        if (retval)
-               return retval;
+               goto err_out;
 
        retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
-       if (retval)
+       if (retval) {
                kobject_put(&cdev->kobj);
+               goto err_out;
+       }
+
+       ir->cdev = cdev;
+
+       return 0;
 
+err_out:
+       kfree(cdev);
        return retval;
 }
 
@@ -214,7 +227,7 @@ int lirc_register_driver(struct lirc_driver *d)
        if (MAX_IRCTL_DEVICES <= d->minor) {
                dev_err(d->dev, "lirc_dev: lirc_register_driver: "
                        "\"minor\" must be between 0 and %d (%d)!\n",
-                       MAX_IRCTL_DEVICES-1, d->minor);
+                       MAX_IRCTL_DEVICES - 1, d->minor);
                err = -EBADRQC;
                goto out;
        }
@@ -369,7 +382,7 @@ int lirc_unregister_driver(int minor)
 
        if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
                printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between "
-                      "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1);
+                      "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES - 1);
                return -EBADRQC;
        }
 
@@ -380,7 +393,7 @@ int lirc_unregister_driver(int minor)
                return -ENOENT;
        }
 
-       cdev = &cdevs[minor];
+       cdev = ir->cdev;
 
        mutex_lock(&lirc_dev_lock);
 
@@ -410,6 +423,7 @@ int lirc_unregister_driver(int minor)
        } else {
                lirc_irctl_cleanup(ir);
                cdev_del(cdev);
+               kfree(cdev);
                kfree(ir);
                irctls[minor] = NULL;
        }
@@ -453,7 +467,7 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
                goto error;
        }
 
-       cdev = &cdevs[iminor(inode)];
+       cdev = ir->cdev;
        if (try_module_get(cdev->owner)) {
                ir->open++;
                retval = ir->d.set_use_inc(ir->d.data);
@@ -484,13 +498,15 @@ EXPORT_SYMBOL(lirc_dev_fop_open);
 int lirc_dev_fop_close(struct inode *inode, struct file *file)
 {
        struct irctl *ir = irctls[iminor(inode)];
-       struct cdev *cdev = &cdevs[iminor(inode)];
+       struct cdev *cdev;
 
        if (!ir) {
                printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
                return -EINVAL;
        }
 
+       cdev = ir->cdev;
+
        dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
 
        WARN_ON(mutex_lock_killable(&lirc_dev_lock));
@@ -503,6 +519,7 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file)
                lirc_irctl_cleanup(ir);
                cdev_del(cdev);
                irctls[ir->d.minor] = NULL;
+               kfree(cdev);
                kfree(ir);
        }
 
index ad927fc..06dfe09 100644 (file)
@@ -108,6 +108,12 @@ static int debug = 1;
 static int debug;
 #endif
 
+#define mce_dbg(dev, fmt, ...)                                 \
+       do {                                                    \
+               if (debug)                                      \
+                       dev_info(dev, fmt, ## __VA_ARGS__);     \
+       } while (0)
+
 /* general constants */
 #define SEND_FLAG_IN_PROGRESS  1
 #define SEND_FLAG_COMPLETE     2
@@ -246,6 +252,9 @@ static struct usb_device_id mceusb_dev_table[] = {
          .driver_info = MCE_GEN2_TX_INV },
        /* SMK eHome Infrared Transceiver */
        { USB_DEVICE(VENDOR_SMK, 0x0338) },
+       /* SMK/I-O Data GV-MC7/RCKIT Receiver */
+       { USB_DEVICE(VENDOR_SMK, 0x0353),
+         .driver_info = MCE_GEN2_NO_TX },
        /* Tatung eHome Infrared Transceiver */
        { USB_DEVICE(VENDOR_TATUNG, 0x9150) },
        /* Shuttle eHome Infrared Transceiver */
@@ -606,12 +615,15 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs)
        if (ir) {
                len = urb->actual_length;
 
-               dev_dbg(ir->dev, "callback called (status=%d len=%d)\n",
+               mce_dbg(ir->dev, "callback called (status=%d len=%d)\n",
                        urb->status, len);
 
                mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true);
        }
 
+       /* the transfer buffer and urb were allocated in mce_request_packet */
+       kfree(urb->transfer_buffer);
+       usb_free_urb(urb);
 }
 
 /* request incoming or send outgoing usb packet - used to initialize remote */
@@ -655,17 +667,17 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
                return;
        }
 
-       dev_dbg(dev, "receive request called (size=%#x)\n", size);
+       mce_dbg(dev, "receive request called (size=%#x)\n", size);
 
        async_urb->transfer_buffer_length = size;
        async_urb->dev = ir->usbdev;
 
        res = usb_submit_urb(async_urb, GFP_ATOMIC);
        if (res) {
-               dev_dbg(dev, "receive request FAILED! (res=%d)\n", res);
+               mce_dbg(dev, "receive request FAILED! (res=%d)\n", res);
                return;
        }
-       dev_dbg(dev, "receive request complete (res=%d)\n", res);
+       mce_dbg(dev, "receive request complete (res=%d)\n", res);
 }
 
 static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
@@ -673,9 +685,9 @@ static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
        mce_request_packet(ir, data, size, MCEUSB_TX);
 }
 
-static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
+static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size)
 {
-       mce_request_packet(ir, data, size, MCEUSB_RX);
+       mce_request_packet(ir, NULL, size, MCEUSB_RX);
 }
 
 /* Send data out the IR blaster port(s) */
@@ -794,7 +806,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
                        ir->carrier = carrier;
                        cmdbuf[2] = MCE_CMD_SIG_END;
                        cmdbuf[3] = MCE_IRDATA_TRAILER;
-                       dev_dbg(ir->dev, "%s: disabling carrier "
+                       mce_dbg(ir->dev, "%s: disabling carrier "
                                "modulation\n", __func__);
                        mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
                        return carrier;
@@ -806,7 +818,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier)
                                ir->carrier = carrier;
                                cmdbuf[2] = prescaler;
                                cmdbuf[3] = divisor;
-                               dev_dbg(ir->dev, "%s: requesting %u HZ "
+                               mce_dbg(ir->dev, "%s: requesting %u HZ "
                                        "carrier\n", __func__, carrier);
 
                                /* Transmit new carrier to mce device */
@@ -879,7 +891,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
                        rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
                                         * US_TO_NS(MCE_TIME_UNIT);
 
-                       dev_dbg(ir->dev, "Storing %s with duration %d\n",
+                       mce_dbg(ir->dev, "Storing %s with duration %d\n",
                                rawir.pulse ? "pulse" : "space",
                                rawir.duration);
 
@@ -911,7 +923,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
                if (ir->parser_state != CMD_HEADER && !ir->rem)
                        ir->parser_state = CMD_HEADER;
        }
-       dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
+       mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
        ir_raw_event_handle(ir->rc);
 }
 
@@ -933,7 +945,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
 
        if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
                ir->send_flags = SEND_FLAG_COMPLETE;
-               dev_dbg(ir->dev, "setup answer received %d bytes\n",
+               mce_dbg(ir->dev, "setup answer received %d bytes\n",
                        buf_len);
        }
 
@@ -951,7 +963,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
 
        case -EPIPE:
        default:
-               dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
+               mce_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
                break;
        }
 
@@ -961,7 +973,6 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
 static void mceusb_gen1_init(struct mceusb_dev *ir)
 {
        int ret;
-       int maxp = ir->len_in;
        struct device *dev = ir->dev;
        char *data;
 
@@ -978,8 +989,8 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
        ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
                              USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
                              data, USB_CTRL_MSG_SZ, HZ * 3);
-       dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
-       dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n",
+       mce_dbg(dev, "%s - ret = %d\n", __func__, ret);
+       mce_dbg(dev, "%s - data[0] = %d, data[1] = %d\n",
                __func__, data[0], data[1]);
 
        /* set feature: bit rate 38400 bps */
@@ -987,71 +998,56 @@ static void mceusb_gen1_init(struct mceusb_dev *ir)
                              USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
                              0xc04e, 0x0000, NULL, 0, HZ * 3);
 
-       dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
+       mce_dbg(dev, "%s - ret = %d\n", __func__, ret);
 
        /* bRequest 4: set char length to 8 bits */
        ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
                              4, USB_TYPE_VENDOR,
                              0x0808, 0x0000, NULL, 0, HZ * 3);
-       dev_dbg(dev, "%s - retB = %d\n", __func__, ret);
+       mce_dbg(dev, "%s - retB = %d\n", __func__, ret);
 
        /* bRequest 2: set handshaking to use DTR/DSR */
        ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
                              2, USB_TYPE_VENDOR,
                              0x0000, 0x0100, NULL, 0, HZ * 3);
-       dev_dbg(dev, "%s - retC = %d\n", __func__, ret);
+       mce_dbg(dev, "%s - retC = %d\n", __func__, ret);
 
        /* device reset */
        mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
-       mce_sync_in(ir, NULL, maxp);
 
        /* get hw/sw revision? */
        mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
-       mce_sync_in(ir, NULL, maxp);
 
        kfree(data);
 };
 
 static void mceusb_gen2_init(struct mceusb_dev *ir)
 {
-       int maxp = ir->len_in;
-
        /* device reset */
        mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
-       mce_sync_in(ir, NULL, maxp);
 
        /* get hw/sw revision? */
        mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
-       mce_sync_in(ir, NULL, maxp);
 
        /* unknown what the next two actually return... */
        mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN));
-       mce_sync_in(ir, NULL, maxp);
        mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
-       mce_sync_in(ir, NULL, maxp);
 }
 
 static void mceusb_get_parameters(struct mceusb_dev *ir)
 {
-       int maxp = ir->len_in;
-
        /* get the carrier and frequency */
        mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
-       mce_sync_in(ir, NULL, maxp);
 
-       if (!ir->flags.no_tx) {
+       if (!ir->flags.no_tx)
                /* get the transmitter bitmask */
                mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
-               mce_sync_in(ir, NULL, maxp);
-       }
 
        /* get receiver timeout value */
        mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
-       mce_sync_in(ir, NULL, maxp);
 
        /* get receiver sensor setting */
        mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
-       mce_sync_in(ir, NULL, maxp);
 }
 
 static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
@@ -1122,7 +1118,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
        bool tx_mask_normal;
        int ir_intfnum;
 
-       dev_dbg(&intf->dev, "%s called\n", __func__);
+       mce_dbg(&intf->dev, "%s called\n", __func__);
 
        idesc  = intf->cur_altsetting;
 
@@ -1150,7 +1146,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
                        ep_in = ep;
                        ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
                        ep_in->bInterval = 1;
-                       dev_dbg(&intf->dev, "acceptable inbound endpoint "
+                       mce_dbg(&intf->dev, "acceptable inbound endpoint "
                                "found\n");
                }
 
@@ -1165,12 +1161,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
                        ep_out = ep;
                        ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
                        ep_out->bInterval = 1;
-                       dev_dbg(&intf->dev, "acceptable outbound endpoint "
+                       mce_dbg(&intf->dev, "acceptable outbound endpoint "
                                "found\n");
                }
        }
        if (ep_in == NULL) {
-               dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
+               mce_dbg(&intf->dev, "inbound and/or endpoint not found\n");
                return -ENODEV;
        }
 
@@ -1215,16 +1211,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
        if (!ir->rc)
                goto rc_dev_fail;
 
-       /* flush buffers on the device */
-       mce_sync_in(ir, NULL, maxp);
-       mce_sync_in(ir, NULL, maxp);
-
        /* wire up inbound data handler */
        usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
                maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval);
        ir->urb_in->transfer_dma = ir->dma_in;
        ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
+       /* flush buffers on the device */
+       mce_dbg(&intf->dev, "Flushing receive buffers\n");
+       mce_flush_rx_buffer(ir, maxp);
+
        /* initialize device */
        if (ir->flags.microsoft_gen1)
                mceusb_gen1_init(ir);
index bf3060e..565f24c 100644 (file)
@@ -991,7 +991,6 @@ static int nvt_open(struct rc_dev *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&nvt->nvt_lock, flags);
-       nvt->in_use = true;
        nvt_enable_cir(nvt);
        spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 
@@ -1004,7 +1003,6 @@ static void nvt_close(struct rc_dev *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&nvt->nvt_lock, flags);
-       nvt->in_use = false;
        nvt_disable_cir(nvt);
        spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 }
index 379795d..1241fc8 100644 (file)
@@ -70,7 +70,6 @@ struct nvt_dev {
        struct ir_raw_event rawir;
 
        spinlock_t nvt_lock;
-       bool in_use;
 
        /* for rx */
        u8 buf[RX_BUF_LEN];
index f57cd56..3186ac7 100644 (file)
@@ -522,18 +522,20 @@ EXPORT_SYMBOL_GPL(rc_g_keycode_from_table);
 /**
  * ir_do_keyup() - internal function to signal the release of a keypress
  * @dev:       the struct rc_dev descriptor of the device
+ * @sync:      whether or not to call input_sync
  *
  * This function is used internally to release a keypress, it must be
  * called with keylock held.
  */
-static void ir_do_keyup(struct rc_dev *dev)
+static void ir_do_keyup(struct rc_dev *dev, bool sync)
 {
        if (!dev->keypressed)
                return;
 
        IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
        input_report_key(dev->input_dev, dev->last_keycode, 0);
-       input_sync(dev->input_dev);
+       if (sync)
+               input_sync(dev->input_dev);
        dev->keypressed = false;
 }
 
@@ -549,7 +551,7 @@ void rc_keyup(struct rc_dev *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&dev->keylock, flags);
-       ir_do_keyup(dev);
+       ir_do_keyup(dev, true);
        spin_unlock_irqrestore(&dev->keylock, flags);
 }
 EXPORT_SYMBOL_GPL(rc_keyup);
@@ -578,7 +580,7 @@ static void ir_timer_keyup(unsigned long cookie)
         */
        spin_lock_irqsave(&dev->keylock, flags);
        if (time_is_before_eq_jiffies(dev->keyup_jiffies))
-               ir_do_keyup(dev);
+               ir_do_keyup(dev, true);
        spin_unlock_irqrestore(&dev->keylock, flags);
 }
 
@@ -597,6 +599,7 @@ void rc_repeat(struct rc_dev *dev)
        spin_lock_irqsave(&dev->keylock, flags);
 
        input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
+       input_sync(dev->input_dev);
 
        if (!dev->keypressed)
                goto out;
@@ -622,29 +625,28 @@ EXPORT_SYMBOL_GPL(rc_repeat);
 static void ir_do_keydown(struct rc_dev *dev, int scancode,
                          u32 keycode, u8 toggle)
 {
-       input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
-
-       /* Repeat event? */
-       if (dev->keypressed &&
-           dev->last_scancode == scancode &&
-           dev->last_toggle == toggle)
-               return;
+       bool new_event = !dev->keypressed ||
+                        dev->last_scancode != scancode ||
+                        dev->last_toggle != toggle;
 
-       /* Release old keypress */
-       ir_do_keyup(dev);
+       if (new_event && dev->keypressed)
+               ir_do_keyup(dev, false);
 
-       dev->last_scancode = scancode;
-       dev->last_toggle = toggle;
-       dev->last_keycode = keycode;
+       input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
 
-       if (keycode == KEY_RESERVED)
-               return;
+       if (new_event && keycode != KEY_RESERVED) {
+               /* Register a keypress */
+               dev->keypressed = true;
+               dev->last_scancode = scancode;
+               dev->last_toggle = toggle;
+               dev->last_keycode = keycode;
+
+               IR_dprintk(1, "%s: key down event, "
+                          "key 0x%04x, scancode 0x%04x\n",
+                          dev->input_name, keycode, scancode);
+               input_report_key(dev->input_dev, keycode, 1);
+       }
 
-       /* Register a keypress */
-       dev->keypressed = true;
-       IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
-                  dev->input_name, keycode, scancode);
-       input_report_key(dev->input_dev, dev->last_keycode, 1);
        input_sync(dev->input_dev);
 }
 
index 10b55c8..89d09a8 100644 (file)
@@ -2,10 +2,10 @@
  * Header for M-5MOLS 8M Pixel camera sensor with ISP
  *
  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim, riverful.kim@samsung.com
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
  *
  * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -106,23 +106,23 @@ struct m5mols_capture {
  * The each value according to each scenemode is recommended in the documents.
  */
 struct m5mols_scenemode {
-       u32 metering;
-       u32 ev_bias;
-       u32 wb_mode;
-       u32 wb_preset;
-       u32 chroma_en;
-       u32 chroma_lvl;
-       u32 edge_en;
-       u32 edge_lvl;
-       u32 af_range;
-       u32 fd_mode;
-       u32 mcc;
-       u32 light;
-       u32 flash;
-       u32 tone;
-       u32 iso;
-       u32 capt_mode;
-       u32 wdr;
+       u8 metering;
+       u8 ev_bias;
+       u8 wb_mode;
+       u8 wb_preset;
+       u8 chroma_en;
+       u8 chroma_lvl;
+       u8 edge_en;
+       u8 edge_lvl;
+       u8 af_range;
+       u8 fd_mode;
+       u8 mcc;
+       u8 light;
+       u8 flash;
+       u8 tone;
+       u8 iso;
+       u8 capt_mode;
+       u8 wdr;
 };
 
 /**
@@ -154,7 +154,6 @@ struct m5mols_version {
        u8      str[VERSION_STRING_SIZE];
        u8      af;
 };
-#define VERSION_SIZE sizeof(struct m5mols_version)
 
 /**
  * struct m5mols_info - M-5MOLS driver data structure
@@ -216,9 +215,9 @@ struct m5mols_info {
        bool lock_ae;
        bool lock_awb;
        u8 resolution;
-       u32 interrupt;
-       u32 mode;
-       u32 mode_save;
+       u8 interrupt;
+       u8 mode;
+       u8 mode_save;
        int (*set_power)(struct device *dev, int on);
 };
 
@@ -256,9 +255,11 @@ struct m5mols_info {
  *   +-------+---+----------+-----+------+------+------+------+
  *   - d[0..3]: according to size1
  */
-int m5mols_read(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
+int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val);
+int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val);
+int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
 int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val);
-int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value);
+int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 value);
 
 /*
  * Mode operation of the M-5MOLS
@@ -280,12 +281,12 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value);
  * The available executing order between each modes are as follows:
  *   PARAMETER <---> MONITOR <---> CAPTURE
  */
-int m5mols_mode(struct m5mols_info *info, u32 mode);
+int m5mols_mode(struct m5mols_info *info, u8 mode);
 
-int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg);
+int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
 int m5mols_sync_controls(struct m5mols_info *info);
 int m5mols_start_capture(struct m5mols_info *info);
-int m5mols_do_scenemode(struct m5mols_info *info, u32 mode);
+int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
 int m5mols_lock_3a(struct m5mols_info *info, bool lock);
 int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
 
index d71a390..d947192 100644 (file)
@@ -2,10 +2,10 @@
  * The Capture code for Fujitsu M-5MOLS ISP
  *
  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim, riverful.kim@samsung.com
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
  *
  * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -58,9 +58,9 @@ static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
 {
        u32 num, den;
 
-       int ret = m5mols_read(sd, addr_num, &num);
+       int ret = m5mols_read_u32(sd, addr_num, &num);
        if (!ret)
-               ret = m5mols_read(sd, addr_den, &den);
+               ret = m5mols_read_u32(sd, addr_den, &den);
        if (ret)
                return ret;
        *val = den == 0 ? 0 : num / den;
@@ -99,20 +99,20 @@ static int m5mols_capture_info(struct m5mols_info *info)
        if (ret)
                return ret;
 
-       ret = m5mols_read(sd, EXIF_INFO_ISO, (u32 *)&exif->iso_speed);
+       ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed);
        if (!ret)
-               ret = m5mols_read(sd, EXIF_INFO_FLASH, (u32 *)&exif->flash);
+               ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash);
        if (!ret)
-               ret = m5mols_read(sd, EXIF_INFO_SDR, (u32 *)&exif->sdr);
+               ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr);
        if (!ret)
-               ret = m5mols_read(sd, EXIF_INFO_QVAL, (u32 *)&exif->qval);
+               ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval);
        if (ret)
                return ret;
 
        if (!ret)
-               ret = m5mols_read(sd, CAPC_IMAGE_SIZE, &info->cap.main);
+               ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main);
        if (!ret)
-               ret = m5mols_read(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
+               ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
        if (!ret)
                info->cap.total = info->cap.main + info->cap.thumb;
 
@@ -122,7 +122,7 @@ static int m5mols_capture_info(struct m5mols_info *info)
 int m5mols_start_capture(struct m5mols_info *info)
 {
        struct v4l2_subdev *sd = &info->sd;
-       u32 resolution = info->resolution;
+       u8 resolution = info->resolution;
        int timeout;
        int ret;
 
index 817c16f..d135d20 100644 (file)
@@ -2,10 +2,10 @@
  * Controls for M-5MOLS 8M Pixel camera sensor with ISP
  *
  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim, riverful.kim@samsung.com
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
  *
  * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -130,7 +130,7 @@ static struct m5mols_scenemode m5mols_default_scenemode[] = {
  *
  * WARNING: The execution order is important. Do not change the order.
  */
-int m5mols_do_scenemode(struct m5mols_info *info, u32 mode)
+int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
 {
        struct v4l2_subdev *sd = &info->sd;
        struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode];
index 76eac26..43c68f5 100644 (file)
@@ -2,10 +2,10 @@
  * Driver for M-5MOLS 8M Pixel camera sensor with ISP
  *
  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim, riverful.kim@samsung.com
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
  *
  * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -133,13 +133,13 @@ static u32 m5mols_swap_byte(u8 *data, u8 length)
 /**
  * m5mols_read -  I2C read function
  * @reg: combination of size, category and command for the I2C packet
+ * @size: desired size of I2C packet
  * @val: read value
  */
-int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val)
+static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
 {
        struct i2c_client *client = v4l2_get_subdevdata(sd);
        u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
-       u8 size = I2C_SIZE(reg);
        u8 category = I2C_CATEGORY(reg);
        u8 cmd = I2C_COMMAND(reg);
        struct i2c_msg msg[2];
@@ -149,11 +149,6 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val)
        if (!client->adapter)
                return -ENODEV;
 
-       if (size != 1 && size != 2 && size != 4) {
-               v4l2_err(sd, "Wrong data size\n");
-               return -EINVAL;
-       }
-
        msg[0].addr = client->addr;
        msg[0].flags = 0;
        msg[0].len = 5;
@@ -184,6 +179,52 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val)
        return 0;
 }
 
+int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
+{
+       u32 val_32;
+       int ret;
+
+       if (I2C_SIZE(reg) != 1) {
+               v4l2_err(sd, "Wrong data size\n");
+               return -EINVAL;
+       }
+
+       ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
+       if (ret)
+               return ret;
+
+       *val = (u8)val_32;
+       return ret;
+}
+
+int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
+{
+       u32 val_32;
+       int ret;
+
+       if (I2C_SIZE(reg) != 2) {
+               v4l2_err(sd, "Wrong data size\n");
+               return -EINVAL;
+       }
+
+       ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
+       if (ret)
+               return ret;
+
+       *val = (u16)val_32;
+       return ret;
+}
+
+int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
+{
+       if (I2C_SIZE(reg) != 4) {
+               v4l2_err(sd, "Wrong data size\n");
+               return -EINVAL;
+       }
+
+       return m5mols_read(sd, I2C_SIZE(reg), reg, val);
+}
+
 /**
  * m5mols_write - I2C command write function
  * @reg: combination of size, category and command for the I2C packet
@@ -231,13 +272,14 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
        return 0;
 }
 
-int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask)
+int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 mask)
 {
-       u32 busy, i;
+       u8 busy;
+       int i;
        int ret;
 
        for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) {
-               ret = m5mols_read(sd, I2C_REG(category, cmd, 1), &busy);
+               ret = m5mols_read_u8(sd, I2C_REG(category, cmd, 1), &busy);
                if (ret < 0)
                        return ret;
                if ((busy & mask) == mask)
@@ -252,14 +294,14 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask)
  * Before writing desired interrupt value the INT_FACTOR register should
  * be read to clear pending interrupts.
  */
-int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg)
+int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
 {
        struct m5mols_info *info = to_m5mols(sd);
-       u32 mask = is_available_af(info) ? REG_INT_AF : 0;
-       u32 dummy;
+       u8 mask = is_available_af(info) ? REG_INT_AF : 0;
+       u8 dummy;
        int ret;
 
-       ret = m5mols_read(sd, SYSTEM_INT_FACTOR, &dummy);
+       ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
        if (!ret)
                ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
        return ret;
@@ -271,7 +313,7 @@ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg)
  * It always accompanies a little delay changing the M-5MOLS mode, so it is
  * needed checking current busy status to guarantee right mode.
  */
-static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode)
+static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
 {
        int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
 
@@ -286,16 +328,16 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode)
  * can be guaranteed only when the sensor is operating in mode which which
  * a command belongs to.
  */
-int m5mols_mode(struct m5mols_info *info, u32 mode)
+int m5mols_mode(struct m5mols_info *info, u8 mode)
 {
        struct v4l2_subdev *sd = &info->sd;
        int ret = -EINVAL;
-       u32 reg;
+       u8 reg;
 
        if (mode < REG_PARAMETER && mode > REG_CAPTURE)
                return ret;
 
-       ret = m5mols_read(sd, SYSTEM_SYSMODE, &reg);
+       ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
        if ((!ret && reg == mode) || ret)
                return ret;
 
@@ -344,41 +386,37 @@ int m5mols_mode(struct m5mols_info *info, u32 mode)
 static int m5mols_get_version(struct v4l2_subdev *sd)
 {
        struct m5mols_info *info = to_m5mols(sd);
-       union {
-               struct m5mols_version ver;
-               u8 bytes[VERSION_SIZE];
-       } version;
-       u32 *value;
-       u8 cmd = CAT0_VER_CUSTOMER;
+       struct m5mols_version *ver = &info->ver;
+       u8 *str = ver->str;
+       int i;
        int ret;
 
-       do {
-               value = (u32 *)&version.bytes[cmd];
-               ret = m5mols_read(sd, SYSTEM_CMD(cmd), value);
-               if (ret)
-                       return ret;
-       } while (cmd++ != CAT0_VER_AWB);
+       ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer);
+       if (!ret)
+               ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project);
+       if (!ret)
+               ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw);
+       if (!ret)
+               ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw);
+       if (!ret)
+               ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param);
+       if (!ret)
+               ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb);
+       if (!ret)
+               ret = m5mols_read_u8(sd, AF_VERSION, &ver->af);
+       if (ret)
+               return ret;
 
-       do {
-               value = (u32 *)&version.bytes[cmd];
-               ret = m5mols_read(sd, SYSTEM_VER_STRING, value);
+       for (i = 0; i < VERSION_STRING_SIZE; i++) {
+               ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]);
                if (ret)
                        return ret;
-               if (cmd >= VERSION_SIZE - 1)
-                       return -EINVAL;
-       } while (version.bytes[cmd++]);
-
-       value = (u32 *)&version.bytes[cmd];
-       ret = m5mols_read(sd, AF_VERSION, value);
-       if (ret)
-               return ret;
+       }
 
-       /* store version information swapped for being readable */
-       info->ver       = version.ver;
-       info->ver.fw    = be16_to_cpu(info->ver.fw);
-       info->ver.hw    = be16_to_cpu(info->ver.hw);
-       info->ver.param = be16_to_cpu(info->ver.param);
-       info->ver.awb   = be16_to_cpu(info->ver.awb);
+       ver->fw = be16_to_cpu(ver->fw);
+       ver->hw = be16_to_cpu(ver->hw);
+       ver->param = be16_to_cpu(ver->param);
+       ver->awb = be16_to_cpu(ver->awb);
 
        v4l2_info(sd, "Manufacturer\t[%s]\n",
                        is_manufacturer(info, REG_SAMSUNG_ELECTRO) ?
@@ -722,7 +760,7 @@ static int m5mols_init_controls(struct m5mols_info *info)
        int ret;
 
        /* Determine value's range & step of controls for various FW version */
-       ret = m5mols_read(sd, AE_MAX_GAIN_MON, (u32 *)&max_exposure);
+       ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure);
        if (!ret)
                step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
        if (ret)
@@ -842,18 +880,18 @@ static void m5mols_irq_work(struct work_struct *work)
        struct m5mols_info *info =
                container_of(work, struct m5mols_info, work_irq);
        struct v4l2_subdev *sd = &info->sd;
-       u32 reg;
+       u8 reg;
        int ret;
 
        if (!is_powered(info) ||
-                       m5mols_read(sd, SYSTEM_INT_FACTOR, &info->interrupt))
+                       m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt))
                return;
 
        switch (info->interrupt & REG_INT_MASK) {
        case REG_INT_AF:
                if (!is_available_af(info))
                        break;
-               ret = m5mols_read(sd, AF_STATUS, &reg);
+               ret = m5mols_read_u8(sd, AF_STATUS, &reg);
                v4l2_dbg(2, m5mols_debug, sd, "AF %s\n",
                         reg == REG_AF_FAIL ? "Failed" :
                         reg == REG_AF_SUCCESS ? "Success" :
index b83e36f..c755bd6 100644 (file)
@@ -2,10 +2,10 @@
  * Register map for M-5MOLS 8M Pixel camera sensor with ISP
  *
  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- * Author: HeungJun Kim, riverful.kim@samsung.com
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
  *
  * Copyright (C) 2009 Samsung Electronics Co., Ltd.
- * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * more specific contents, see definition if file m5mols.h.
  */
 #define CAT0_VER_CUSTOMER      0x00    /* customer version */
-#define CAT0_VER_AWB           0x09    /* Auto WB version */
+#define CAT0_VER_PROJECT       0x01    /* project version */
+#define CAT0_VER_FIRMWARE      0x02    /* Firmware version */
+#define CAT0_VER_HARDWARE      0x04    /* Hardware version */
+#define CAT0_VER_PARAMETER     0x06    /* Parameter version */
+#define CAT0_VER_AWB           0x08    /* Auto WB version */
 #define CAT0_VER_STRING                0x0a    /* string including M-5MOLS */
 #define CAT0_SYSMODE           0x0b    /* SYSTEM mode register */
 #define CAT0_STATUS            0x0c    /* SYSTEM mode status register */
 #define CAT0_INT_FACTOR                0x10    /* interrupt pending register */
 #define CAT0_INT_ENABLE                0x11    /* interrupt enable register */
 
+#define SYSTEM_VER_CUSTOMER    I2C_REG(CAT_SYSTEM, CAT0_VER_CUSTOMER, 1)
+#define SYSTEM_VER_PROJECT     I2C_REG(CAT_SYSTEM, CAT0_VER_PROJECT, 1)
+#define SYSTEM_VER_FIRMWARE    I2C_REG(CAT_SYSTEM, CAT0_VER_FIRMWARE, 2)
+#define SYSTEM_VER_HARDWARE    I2C_REG(CAT_SYSTEM, CAT0_VER_HARDWARE, 2)
+#define SYSTEM_VER_PARAMETER   I2C_REG(CAT_SYSTEM, CAT0_VER_PARAMETER, 2)
+#define SYSTEM_VER_AWB         I2C_REG(CAT_SYSTEM, CAT0_VER_AWB, 2)
+
 #define SYSTEM_SYSMODE         I2C_REG(CAT_SYSTEM, CAT0_SYSMODE, 1)
 #define REG_SYSINIT            0x00    /* SYSTEM mode */
 #define REG_PARAMETER          0x01    /* PARAMETER mode */
 #define REG_CAP_START_MAIN     0x01
 #define REG_CAP_START_THUMB    0x03
 
-#define CAPC_IMAGE_SIZE                I2C_REG(CAT_CAPT_CTRL, CATC_CAP_IMAGE_SIZE, 1)
-#define CAPC_THUMB_SIZE                I2C_REG(CAT_CAPT_CTRL, CATC_CAP_THUMB_SIZE, 1)
+#define CAPC_IMAGE_SIZE                I2C_REG(CAT_CAPT_CTRL, CATC_CAP_IMAGE_SIZE, 4)
+#define CAPC_THUMB_SIZE                I2C_REG(CAT_CAPT_CTRL, CATC_CAP_THUMB_SIZE, 4)
 
 /*
  * Category F - Flash
index bc0c23a..63f8a0c 100644 (file)
@@ -444,12 +444,9 @@ static int mx1_camera_add_device(struct soc_camera_device *icd)
 {
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct mx1_camera_dev *pcdev = ici->priv;
-       int ret;
 
-       if (pcdev->icd) {
-               ret = -EBUSY;
-               goto ebusy;
-       }
+       if (pcdev->icd)
+               return -EBUSY;
 
        dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n",
                 icd->devnum);
@@ -458,8 +455,7 @@ static int mx1_camera_add_device(struct soc_camera_device *icd)
 
        pcdev->icd = icd;
 
-ebusy:
-       return ret;
+       return 0;
 }
 
 static void mx1_camera_remove_device(struct soc_camera_device *icd)
index 4ada9be..4d07c58 100644 (file)
@@ -982,6 +982,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
        startindex = (vout->vid == OMAP_VIDEO1) ?
                video1_numbuffers : video2_numbuffers;
 
+       /* Check the size of the buffer */
+       if (*size > vout->buffer_size) {
+               v4l2_err(&vout->vid_dev->v4l2_dev,
+                               "buffer allocation mismatch [%u] [%u]\n",
+                               *size, vout->buffer_size);
+               return -ENOMEM;
+       }
+
        for (i = startindex; i < *count; i++) {
                vout->buffer_size = *size;
 
@@ -1228,6 +1236,14 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
                                (vma->vm_pgoff << PAGE_SHIFT));
                return -EINVAL;
        }
+       /* Check the size of the buffer */
+       if (size > vout->buffer_size) {
+               v4l2_err(&vout->vid_dev->v4l2_dev,
+                               "insufficient memory [%lu] [%u]\n",
+                               size, vout->buffer_size);
+               return -ENOMEM;
+       }
+
        q->bufs[i]->baddr = vma->vm_start;
 
        vma->vm_flags |= VM_RESERVED;
@@ -2391,7 +2407,7 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev)
                /* Register the Video device with V4L2
                 */
                vfd = vout->vfd;
-               if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) {
+               if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {
                        dev_err(&pdev->dev, ": Could not register "
                                        "Video for Linux device\n");
                        vfd->minor = -1;
index 2aa6a76..8ae7481 100644 (file)
@@ -193,7 +193,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
                return -EINVAL;
 
        if (cpu_is_omap24xx()) {
-               if (crop->height != win->w.height) {
+               if (try_crop.height != win->w.height) {
                        /* If we're resizing vertically, we can't support a
                         * crop width wider than 768 pixels.
                         */
@@ -202,7 +202,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
                }
        }
        /* vertical resizing */
-       vresize = (1024 * crop->height) / win->w.height;
+       vresize = (1024 * try_crop.height) / win->w.height;
        if (cpu_is_omap24xx() && (vresize > 2048))
                vresize = 2048;
        else if (cpu_is_omap34xx() && (vresize > 4096))
@@ -221,7 +221,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix,
                        try_crop.height = 2;
        }
        /* horizontal resizing */
-       hresize = (1024 * crop->width) / win->w.width;
+       hresize = (1024 * try_crop.width) / win->w.width;
        if (cpu_is_omap24xx() && (hresize > 2048))
                hresize = 2048;
        else if (cpu_is_omap34xx() && (hresize > 4096))
index c9fd04e..94b6ed8 100644 (file)
@@ -1748,7 +1748,7 @@ static int isp_register_entities(struct isp_device *isp)
                goto done;
 
        /* Register external entities */
-       for (subdevs = pdata->subdevs; subdevs->subdevs; ++subdevs) {
+       for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
                struct v4l2_subdev *sensor;
                struct media_entity *input;
                unsigned int flags;
index 1593f8d..760b4de 100644 (file)
@@ -1414,7 +1414,7 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
        {
                ARG_DEF(struct pwc_probe, probe)
 
-               strcpy(ARGR(probe).name, pdev->vdev->name);
+               strcpy(ARGR(probe).name, pdev->vdev.name);
                ARGR(probe).type = pdev->type;
                ARG_OUT(probe)
                break;
index 356cd42..b0bde5a 100644 (file)
@@ -40,7 +40,7 @@
    Oh yes, convention: to disctinguish between all the various pointers to
    device-structures, I use these names for the pointer variables:
    udev: struct usb_device *
-   vdev: struct video_device *
+   vdev: struct video_device (member of pwc_dev)
    pdev: struct pwc_devive *
 */
 
@@ -152,6 +152,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
                          size_t count, loff_t *ppos);
 static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
 static int  pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
+static void pwc_video_release(struct video_device *vfd);
 
 static const struct v4l2_file_operations pwc_fops = {
        .owner =        THIS_MODULE,
@@ -164,41 +165,11 @@ static const struct v4l2_file_operations pwc_fops = {
 };
 static struct video_device pwc_template = {
        .name =         "Philips Webcam",       /* Filled in later */
-       .release =      video_device_release,
+       .release =      pwc_video_release,
        .fops =         &pwc_fops,
+       .ioctl_ops =    &pwc_ioctl_ops,
 };
 
-/***************************************************************************/
-
-/* Okay, this is some magic that I worked out and the reasoning behind it...
-
-   The biggest problem with any USB device is of course: "what to do
-   when the user unplugs the device while it is in use by an application?"
-   We have several options:
-   1) Curse them with the 7 plagues when they do (requires divine intervention)
-   2) Tell them not to (won't work: they'll do it anyway)
-   3) Oops the kernel (this will have a negative effect on a user's uptime)
-   4) Do something sensible.
-
-   Of course, we go for option 4.
-
-   It happens that this device will be linked to two times, once from
-   usb_device and once from the video_device in their respective 'private'
-   pointers. This is done when the device is probed() and all initialization
-   succeeded. The pwc_device struct links back to both structures.
-
-   When a device is unplugged while in use it will be removed from the
-   list of known USB devices; I also de-register it as a V4L device, but
-   unfortunately I can't free the memory since the struct is still in use
-   by the file descriptor. This free-ing is then deferend until the first
-   opportunity. Crude, but it works.
-
-   A small 'advantage' is that if a user unplugs the cam and plugs it back
-   in, it should get assigned the same video device minor, but unfortunately
-   it's non-trivial to re-link the cam back to the video device... (that
-   would surely be magic! :))
-*/
-
 /***************************************************************************/
 /* Private functions */
 
@@ -1016,16 +987,15 @@ static ssize_t show_snapshot_button_status(struct device *class_dev,
 static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
                   NULL);
 
-static int pwc_create_sysfs_files(struct video_device *vdev)
+static int pwc_create_sysfs_files(struct pwc_device *pdev)
 {
-       struct pwc_device *pdev = video_get_drvdata(vdev);
        int rc;
 
-       rc = device_create_file(&vdev->dev, &dev_attr_button);
+       rc = device_create_file(&pdev->vdev.dev, &dev_attr_button);
        if (rc)
                goto err;
        if (pdev->features & FEATURE_MOTOR_PANTILT) {
-               rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt);
+               rc = device_create_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
                if (rc)
                        goto err_button;
        }
@@ -1033,19 +1003,17 @@ static int pwc_create_sysfs_files(struct video_device *vdev)
        return 0;
 
 err_button:
-       device_remove_file(&vdev->dev, &dev_attr_button);
+       device_remove_file(&pdev->vdev.dev, &dev_attr_button);
 err:
        PWC_ERROR("Could not create sysfs files.\n");
        return rc;
 }
 
-static void pwc_remove_sysfs_files(struct video_device *vdev)
+static void pwc_remove_sysfs_files(struct pwc_device *pdev)
 {
-       struct pwc_device *pdev = video_get_drvdata(vdev);
-
        if (pdev->features & FEATURE_MOTOR_PANTILT)
-               device_remove_file(&vdev->dev, &dev_attr_pan_tilt);
-       device_remove_file(&vdev->dev, &dev_attr_button);
+               device_remove_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
+       device_remove_file(&pdev->vdev.dev, &dev_attr_button);
 }
 
 #ifdef CONFIG_USB_PWC_DEBUG
@@ -1106,7 +1074,7 @@ static int pwc_video_open(struct file *file)
                if (ret >= 0)
                {
                        PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
-                                       pdev->vdev->name,
+                                       pdev->vdev.name,
                                        pwc_sensor_type_to_string(i), i);
                }
        }
@@ -1180,16 +1148,15 @@ static int pwc_video_open(struct file *file)
        return 0;
 }
 
-
-static void pwc_cleanup(struct pwc_device *pdev)
+static void pwc_video_release(struct video_device *vfd)
 {
-       pwc_remove_sysfs_files(pdev->vdev);
-       video_unregister_device(pdev->vdev);
+       struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev);
+       int hint;
 
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
-       if (pdev->button_dev)
-               input_unregister_device(pdev->button_dev);
-#endif
+       /* search device_hint[] table if we occupy a slot, by any chance */
+       for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+               if (device_hint[hint].pdev == pdev)
+                       device_hint[hint].pdev = NULL;
 
        kfree(pdev);
 }
@@ -1199,7 +1166,7 @@ static int pwc_video_close(struct file *file)
 {
        struct video_device *vdev = file->private_data;
        struct pwc_device *pdev;
-       int i, hint;
+       int i;
 
        PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
 
@@ -1234,12 +1201,6 @@ static int pwc_video_close(struct file *file)
                }
                pdev->vopen--;
                PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
-       } else {
-               pwc_cleanup(pdev);
-               /* search device_hint[] table if we occupy a slot, by any chance */
-               for (hint = 0; hint < MAX_DEV_HINTS; hint++)
-                       if (device_hint[hint].pdev == pdev)
-                               device_hint[hint].pdev = NULL;
        }
 
        return 0;
@@ -1715,19 +1676,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        init_waitqueue_head(&pdev->frameq);
        pdev->vcompression = pwc_preferred_compression;
 
-       /* Allocate video_device structure */
-       pdev->vdev = video_device_alloc();
-       if (!pdev->vdev) {
-               PWC_ERROR("Err, cannot allocate video_device struture. Failing probe.");
-               rc = -ENOMEM;
-               goto err_free_mem;
-       }
-       memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
-       pdev->vdev->parent = &intf->dev;
-       pdev->vdev->lock = &pdev->modlock;
-       pdev->vdev->ioctl_ops = &pwc_ioctl_ops;
-       strcpy(pdev->vdev->name, name);
-       video_set_drvdata(pdev->vdev, pdev);
+       /* Init video_device structure */
+       memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
+       pdev->vdev.parent = &intf->dev;
+       pdev->vdev.lock = &pdev->modlock;
+       strcpy(pdev->vdev.name, name);
+       video_set_drvdata(&pdev->vdev, pdev);
 
        pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
        PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
@@ -1746,8 +1700,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
                }
        }
 
-       pdev->vdev->release = video_device_release;
-
        /* occupy slot */
        if (hint < MAX_DEV_HINTS)
                device_hint[hint].pdev = pdev;
@@ -1759,16 +1711,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        pwc_set_leds(pdev, 0, 0);
        pwc_camera_power(pdev, 0);
 
-       rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
+       rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
        if (rc < 0) {
                PWC_ERROR("Failed to register as video device (%d).\n", rc);
-               goto err_video_release;
+               goto err_free_mem;
        }
-       rc = pwc_create_sysfs_files(pdev->vdev);
+       rc = pwc_create_sysfs_files(pdev);
        if (rc)
                goto err_video_unreg;
 
-       PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev));
+       PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));
 
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
        /* register webcam snapshot button input device */
@@ -1776,7 +1728,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        if (!pdev->button_dev) {
                PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
                rc = -ENOMEM;
-               pwc_remove_sysfs_files(pdev->vdev);
+               pwc_remove_sysfs_files(pdev);
                goto err_video_unreg;
        }
 
@@ -1794,7 +1746,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        if (rc) {
                input_free_device(pdev->button_dev);
                pdev->button_dev = NULL;
-               pwc_remove_sysfs_files(pdev->vdev);
+               pwc_remove_sysfs_files(pdev);
                goto err_video_unreg;
        }
 #endif
@@ -1804,10 +1756,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 err_video_unreg:
        if (hint < MAX_DEV_HINTS)
                device_hint[hint].pdev = NULL;
-       video_unregister_device(pdev->vdev);
-       pdev->vdev = NULL;      /* So we don't try to release it below */
-err_video_release:
-       video_device_release(pdev->vdev);
+       video_unregister_device(&pdev->vdev);
 err_free_mem:
        kfree(pdev);
        return rc;
@@ -1816,10 +1765,8 @@ err_free_mem:
 /* The user yanked out the cable... */
 static void usb_pwc_disconnect(struct usb_interface *intf)
 {
-       struct pwc_device *pdev;
-       int hint;
+       struct pwc_device *pdev  = usb_get_intfdata(intf);
 
-       pdev = usb_get_intfdata (intf);
        mutex_lock(&pdev->modlock);
        usb_set_intfdata (intf, NULL);
        if (pdev == NULL) {
@@ -1836,30 +1783,25 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
        }
 
        /* We got unplugged; this is signalled by an EPIPE error code */
-       if (pdev->vopen) {
-               PWC_INFO("Disconnected while webcam is in use!\n");
-               pdev->error_status = EPIPE;
-       }
+       pdev->error_status = EPIPE;
+       pdev->unplugged = 1;
 
        /* Alert waiting processes */
        wake_up_interruptible(&pdev->frameq);
-       /* Wait until device is closed */
-       if (pdev->vopen) {
-               pdev->unplugged = 1;
-               pwc_iso_stop(pdev);
-       } else {
-               /* Device is closed, so we can safely unregister it */
-               PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
 
-disconnect_out:
-               /* search device_hint[] table if we occupy a slot, by any chance */
-               for (hint = 0; hint < MAX_DEV_HINTS; hint++)
-                       if (device_hint[hint].pdev == pdev)
-                               device_hint[hint].pdev = NULL;
-       }
+       /* No need to keep the urbs around after disconnection */
+       pwc_isoc_cleanup(pdev);
 
+disconnect_out:
        mutex_unlock(&pdev->modlock);
-       pwc_cleanup(pdev);
+
+       pwc_remove_sysfs_files(pdev);
+       video_unregister_device(&pdev->vdev);
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+       if (pdev->button_dev)
+               input_unregister_device(pdev->button_dev);
+#endif
 }
 
 
index e947766..083f8b1 100644 (file)
@@ -162,9 +162,9 @@ struct pwc_imgbuf
 
 struct pwc_device
 {
-   struct video_device *vdev;
+       struct video_device vdev;
 
-   /* Pointer to our usb_device */
+   /* Pointer to our usb_device, may be NULL after unplug */
    struct usb_device *udev;
 
    int type;                    /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
index d142b40..81b4a82 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Samsung S5P SoC series camera interface (camera capture) driver
+ * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
  *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd
+ * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
  * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -262,12 +262,7 @@ static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
 {
        if (!fr || plane >= fr->fmt->memplanes)
                return 0;
-
-       dbg("%s: w: %d. h: %d. depth[%d]: %d",
-           __func__, fr->width, fr->height, plane, fr->fmt->depth[plane]);
-
        return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
-
 }
 
 static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
@@ -283,24 +278,14 @@ static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
 
        *num_planes = fmt->memplanes;
 
-       dbg("%s, buffer count=%d, plane count=%d",
-           __func__, *num_buffers, *num_planes);
-
        for (i = 0; i < fmt->memplanes; i++) {
                sizes[i] = get_plane_size(&ctx->d_frame, i);
-               dbg("plane: %u, plane_size: %lu", i, sizes[i]);
                allocators[i] = ctx->fimc_dev->alloc_ctx;
        }
 
        return 0;
 }
 
-static int buffer_init(struct vb2_buffer *vb)
-{
-       /* TODO: */
-       return 0;
-}
-
 static int buffer_prepare(struct vb2_buffer *vb)
 {
        struct vb2_queue *vq = vb->vb2_queue;
@@ -380,7 +365,6 @@ static struct vb2_ops fimc_capture_qops = {
        .queue_setup            = queue_setup,
        .buf_prepare            = buffer_prepare,
        .buf_queue              = buffer_queue,
-       .buf_init               = buffer_init,
        .wait_prepare           = fimc_unlock,
        .wait_finish            = fimc_lock,
        .start_streaming        = start_streaming,
@@ -903,6 +887,7 @@ err_vd_reg:
 err_v4l2_reg:
        v4l2_device_unregister(v4l2_dev);
 err_info:
+       kfree(ctx);
        dev_err(&fimc->pdev->dev, "failed to install\n");
        return ret;
 }
index dc91a85..bdf19ad 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * S5P camera interface (video postprocessor) driver
+ * Samsung S5P/EXYNOS4 SoC series camera interface (video postprocessor) driver
  *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd
- *
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -42,7 +41,6 @@ static struct fimc_fmt fimc_formats[] = {
                .color          = S5P_FIMC_RGB565,
                .memplanes      = 1,
                .colplanes      = 1,
-               .mbus_code      = V4L2_MBUS_FMT_RGB565_2X8_BE,
                .flags          = FMT_FLAGS_M2M,
        }, {
                .name           = "BGR666",
@@ -232,11 +230,7 @@ static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
                        return 0;
                }
        }
-
        *shift = 0, *ratio = 1;
-
-       dbg("s: %d, t: %d, shift: %d, ratio: %d",
-           src, tar, *shift, *ratio);
        return 0;
 }
 
@@ -268,10 +262,8 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
                err("invalid source size: %d x %d", sx, sy);
                return -EINVAL;
        }
-
        sc->real_width = sx;
        sc->real_height = sy;
-       dbg("sx= %d, sy= %d, tx= %d, ty= %d", sx, sy, tx, ty);
 
        ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor);
        if (ret)
@@ -711,22 +703,18 @@ static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
        f = ctx_get_frame(ctx, vq->type);
        if (IS_ERR(f))
                return PTR_ERR(f);
-
        /*
         * Return number of non-contigous planes (plane buffers)
         * depending on the configured color format.
         */
-       if (f->fmt)
-               *num_planes = f->fmt->memplanes;
+       if (!f->fmt)
+               return -EINVAL;
 
+       *num_planes = f->fmt->memplanes;
        for (i = 0; i < f->fmt->memplanes; i++) {
-               sizes[i] = (f->width * f->height * f->fmt->depth[i]) >> 3;
+               sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8;
                allocators[i] = ctx->fimc_dev->alloc_ctx;
        }
-
-       if (*num_buffers == 0)
-               *num_buffers = 1;
-
        return 0;
 }
 
@@ -852,7 +840,7 @@ struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask)
 
        for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
                fmt = &fimc_formats[i];
-               if (fmt->fourcc == f->fmt.pix.pixelformat &&
+               if (fmt->fourcc == f->fmt.pix_mp.pixelformat &&
                   (fmt->flags & mask))
                        break;
        }
index 3beb1e5..1f70772 100644 (file)
@@ -1,7 +1,5 @@
 /*
- * Copyright (c) 2010 Samsung Electronics
- *
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
+ * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
  *
  * 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
@@ -135,9 +133,10 @@ enum fimc_color_fmt {
  * @name: format description
  * @fourcc: the fourcc code for this format, 0 if not applicable
  * @color: the corresponding fimc_color_fmt
- * @depth: per plane driver's private 'number of bits per pixel'
  * @memplanes: number of physically non-contiguous data planes
  * @colplanes: number of physically contiguous data planes
+ * @depth: per plane driver's private 'number of bits per pixel'
+ * @flags: flags indicating which operation mode format applies to
  */
 struct fimc_fmt {
        enum v4l2_mbus_pixelcode mbus_code;
@@ -171,7 +170,7 @@ struct fimc_dma_offset {
 };
 
 /**
- * struct fimc_effect - the configuration data for the "Arbitrary" image effect
+ * struct fimc_effect - color effect information
  * @type:      effect type
  * @pat_cb:    cr value when type is "arbitrary"
  * @pat_cr:    cr value when type is "arbitrary"
@@ -184,7 +183,6 @@ struct fimc_effect {
 
 /**
  * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
- *
  * @scaleup_h:         flag indicating scaling up horizontally
  * @scaleup_v:         flag indicating scaling up vertically
  * @copy_mode:         flag indicating transparent DMA transfer (no scaling
@@ -220,7 +218,6 @@ struct fimc_scaler {
 
 /**
  * struct fimc_addr - the FIMC physical address set for DMA
- *
  * @y:  luminance plane physical address
  * @cb:         Cb plane physical address
  * @cr:         Cr plane physical address
@@ -234,6 +231,7 @@ struct fimc_addr {
 /**
  * struct fimc_vid_buffer - the driver's video buffer
  * @vb:    v4l videobuf buffer
+ * @list:  linked list structure for buffer queue
  * @paddr: precalculated physical address set
  * @index: buffer index for the output DMA engine
  */
@@ -254,11 +252,10 @@ struct fimc_vid_buffer {
  * @offs_v:    image vertical pixel offset
  * @width:     image pixel width
  * @height:    image pixel weight
- * @paddr:     image frame buffer physical addresses
- * @buf_cnt:   number of buffers depending on a color format
  * @payload:   image size in bytes (w x h x bpp)
- * @color:     color format
+ * @paddr:     image frame buffer physical addresses
  * @dma_offset:        DMA offset in bytes
+ * @fmt:       fimc color format pointer
  */
 struct fimc_frame {
        u32     f_width;
@@ -390,21 +387,22 @@ struct fimc_ctx;
 
 /**
  * struct fimc_dev - abstraction for FIMC entity
- *
  * @slock:     the spinlock protecting this data structure
  * @lock:      the mutex protecting this data structure
  * @pdev:      pointer to the FIMC platform device
  * @pdata:     pointer to the device platform data
+ * @variant:   the IP variant information
  * @id:                FIMC device index (0..FIMC_MAX_DEVS)
  * @num_clocks: the number of clocks managed by this device instance
- * @clock[]:   the clocks required for FIMC operation
+ * @clock:     clocks required for FIMC operation
  * @regs:      the mapped hardware registers
  * @regs_res:  the resource claimed for IO registers
- * @irq:       interrupt number of the FIMC subdevice
- * @irq_queue:
+ * @irq:       FIMC interrupt number
+ * @irq_queue: interrupt handler waitqueue
  * @m2m:       memory-to-memory V4L2 device information
  * @vid_cap:   camera capture device information
  * @state:     flags used to synchronize m2m and capture mode operation
+ * @alloc_ctx: videobuf2 memory allocator context
  */
 struct fimc_dev {
        spinlock_t                      slock;
@@ -427,8 +425,7 @@ struct fimc_dev {
 
 /**
  * fimc_ctx - the device context data
- *
- * @lock:              mutex protecting this data structure
+ * @slock:             spinlock protecting this data structure
  * @s_frame:           source frame properties
  * @d_frame:           destination frame properties
  * @out_order_1p:      output 1-plane YCBCR order
index ff6c0e9..d4ee24b 100644 (file)
@@ -963,7 +963,7 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
         * to work with other protocols.
         */
        if (!ir->active) {
-               timeout = jiffies + jiffies_to_msecs(15);
+               timeout = jiffies + msecs_to_jiffies(15);
                mod_timer(&ir->timer, timeout);
                ir->active = true;
        }
index c3ab0c8..48fea37 100644 (file)
@@ -27,14 +27,20 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
        struct uvc_entity *entity)
 {
        const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
-       struct uvc_entity *remote;
+       struct media_entity *sink;
        unsigned int i;
-       u8 remote_pad;
-       int ret = 0;
+       int ret;
+
+       sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
+            ? (entity->vdev ? &entity->vdev->entity : NULL)
+            : &entity->subdev.entity;
+       if (sink == NULL)
+               return 0;
 
        for (i = 0; i < entity->num_pads; ++i) {
                struct media_entity *source;
-               struct media_entity *sink;
+               struct uvc_entity *remote;
+               u8 remote_pad;
 
                if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK))
                        continue;
@@ -43,10 +49,11 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
                if (remote == NULL)
                        return -EINVAL;
 
-               source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING)
-                      ? &remote->vdev->entity : &remote->subdev.entity;
-               sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
-                    ? &entity->vdev->entity : &entity->subdev.entity;
+               source = (UVC_ENTITY_TYPE(remote) != UVC_TT_STREAMING)
+                      ? (remote->vdev ? &remote->vdev->entity : NULL)
+                      : &remote->subdev.entity;
+               if (source == NULL)
+                       continue;
 
                remote_pad = remote->num_pads - 1;
                ret = media_entity_create_link(source, remote_pad,
@@ -55,11 +62,10 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
                        return ret;
        }
 
-       if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING)
-               ret = v4l2_device_register_subdev(&chain->dev->vdev,
-                                                 &entity->subdev);
+       if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
+               return 0;
 
-       return ret;
+       return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev);
 }
 
 static struct v4l2_subdev_ops uvc_subdev_ops = {
@@ -84,9 +90,11 @@ static int uvc_mc_init_entity(struct uvc_entity *entity)
 
                ret = media_entity_init(&entity->subdev.entity,
                                        entity->num_pads, entity->pads, 0);
-       } else
+       } else if (entity->vdev != NULL) {
                ret = media_entity_init(&entity->vdev->entity,
                                        entity->num_pads, entity->pads, 0);
+       } else
+               ret = 0;
 
        return ret;
 }
index 109a063..f90ce9f 100644 (file)
@@ -104,6 +104,8 @@ static int __uvc_free_buffers(struct uvc_video_queue *queue)
        }
 
        if (queue->count) {
+               uvc_queue_cancel(queue, 0);
+               INIT_LIST_HEAD(&queue->mainqueue);
                vfree(queue->mem);
                queue->count = 0;
        }
index fc766b9..4999479 100644 (file)
@@ -1255,8 +1255,10 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable)
 
        /* Commit the streaming parameters. */
        ret = uvc_commit_video(stream, &stream->ctrl);
-       if (ret < 0)
+       if (ret < 0) {
+               uvc_queue_enable(&stream->queue, 0);
                return ret;
+       }
 
        return uvc_init_video(stream, GFP_KERNEL);
 }
index 19d5ae2..06f1400 100644 (file)
@@ -167,6 +167,12 @@ static void v4l2_device_release(struct device *cd)
 
        mutex_unlock(&videodev_lock);
 
+#if defined(CONFIG_MEDIA_CONTROLLER)
+       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+           vdev->vfl_type != VFL_TYPE_SUBDEV)
+               media_device_unregister_entity(&vdev->entity);
+#endif
+
        /* Release video_device and perform other
           cleanups as needed. */
        vdev->release(vdev);
@@ -389,9 +395,6 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
 static int v4l2_open(struct inode *inode, struct file *filp)
 {
        struct video_device *vdev;
-#if defined(CONFIG_MEDIA_CONTROLLER)
-       struct media_entity *entity = NULL;
-#endif
        int ret = 0;
 
        /* Check if the video device is available */
@@ -405,17 +408,6 @@ static int v4l2_open(struct inode *inode, struct file *filp)
        /* and increase the device refcount */
        video_get(vdev);
        mutex_unlock(&videodev_lock);
-#if defined(CONFIG_MEDIA_CONTROLLER)
-       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-           vdev->vfl_type != VFL_TYPE_SUBDEV) {
-               entity = media_entity_get(&vdev->entity);
-               if (!entity) {
-                       ret = -EBUSY;
-                       video_put(vdev);
-                       return ret;
-               }
-       }
-#endif
        if (vdev->fops->open) {
                if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
                        ret = -ERESTARTSYS;
@@ -431,14 +423,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)
 
 err:
        /* decrease the refcount in case of an error */
-       if (ret) {
-#if defined(CONFIG_MEDIA_CONTROLLER)
-               if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-                   vdev->vfl_type != VFL_TYPE_SUBDEV)
-                       media_entity_put(entity);
-#endif
+       if (ret)
                video_put(vdev);
-       }
        return ret;
 }
 
@@ -455,11 +441,6 @@ static int v4l2_release(struct inode *inode, struct file *filp)
                if (vdev->lock)
                        mutex_unlock(vdev->lock);
        }
-#if defined(CONFIG_MEDIA_CONTROLLER)
-       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-           vdev->vfl_type != VFL_TYPE_SUBDEV)
-               media_entity_put(&vdev->entity);
-#endif
        /* decrease the refcount unconditionally since the release()
           return value is ignored. */
        video_put(vdev);
@@ -754,12 +735,6 @@ void video_unregister_device(struct video_device *vdev)
        if (!vdev || !video_is_registered(vdev))
                return;
 
-#if defined(CONFIG_MEDIA_CONTROLLER)
-       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-           vdev->vfl_type != VFL_TYPE_SUBDEV)
-               media_device_unregister_entity(&vdev->entity);
-#endif
-
        mutex_lock(&videodev_lock);
        /* This must be in a critical section to prevent a race with v4l2_open.
         * Once this bit has been cleared video_get may never be called again.
index 6ba1461..3015e60 100644 (file)
@@ -492,13 +492,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
                return -EINVAL;
        }
 
-       /*
-        * If the same number of buffers and memory access method is requested
-        * then return immediately.
-        */
-       if (q->memory == req->memory && req->count == q->num_buffers)
-               return 0;
-
        if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) {
                /*
                 * We already have buffers allocated, so first check if they
@@ -539,9 +532,9 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
        /* Finally, allocate buffers and video memory */
        ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes,
                                plane_sizes);
-       if (ret < 0) {
-               dprintk(1, "Memory allocation failed with error: %d\n", ret);
-               return ret;
+       if (ret == 0) {
+               dprintk(1, "Memory allocation failed\n");
+               return -ENOMEM;
        }
 
        /*
@@ -1196,6 +1189,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
         * has not already dequeued before initiating cancel.
         */
        INIT_LIST_HEAD(&q->done_list);
+       atomic_set(&q->queued_count, 0);
        wake_up_all(&q->done_wq);
 
        /*
index b2d9485..10a20d9 100644 (file)
@@ -62,7 +62,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size)
                goto fail_pages_array_alloc;
 
        for (i = 0; i < buf->sg_desc.num_pages; ++i) {
-               buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
+               buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN);
                if (NULL == buf->pages[i])
                        goto fail_pages_alloc;
                sg_set_page(&buf->sg_desc.sglist[i],
index 0f09c05..6ca938a 100644 (file)
@@ -728,6 +728,9 @@ config MFD_TPS65910
          if you say yes here you get support for the TPS65910 series of
          Power Management chips.
 
+config TPS65911_COMPARATOR
+       tristate
+
 endif # MFD_SUPPORT
 
 menu "Multimedia Capabilities Port drivers"
index efe3cc3..d7d47d2 100644 (file)
@@ -94,3 +94,4 @@ obj-$(CONFIG_MFD_OMAP_USB_HOST)       += omap-usb-host.o
 obj-$(CONFIG_MFD_PM8921_CORE)  += pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ)   += pm8xxx-irq.o
 obj-$(CONFIG_MFD_TPS65910)     += tps65910.o tps65910-irq.o
+obj-$(CONFIG_TPS65911_COMPARATOR)      += tps65911-comparator.o
index 8552195..1717144 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/spinlock.h>
 #include <linux/gpio.h>
 #include <plat/usb.h>
-#include <linux/pm_runtime.h>
 
 #define USBHS_DRIVER_NAME      "usbhs-omap"
 #define OMAP_EHCI_DEVICE       "ehci-omap"
 
 
 struct usbhs_hcd_omap {
+       struct clk                      *usbhost_ick;
+       struct clk                      *usbhost_hs_fck;
+       struct clk                      *usbhost_fs_fck;
        struct clk                      *xclk60mhsp1_ck;
        struct clk                      *xclk60mhsp2_ck;
        struct clk                      *utmi_p1_fck;
@@ -156,6 +158,8 @@ struct usbhs_hcd_omap {
        struct clk                      *usbhost_p2_fck;
        struct clk                      *usbtll_p2_fck;
        struct clk                      *init_60m_fclk;
+       struct clk                      *usbtll_fck;
+       struct clk                      *usbtll_ick;
 
        void __iomem                    *uhh_base;
        void __iomem                    *tll_base;
@@ -349,13 +353,46 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
        omap->platdata.ehci_data = pdata->ehci_data;
        omap->platdata.ohci_data = pdata->ohci_data;
 
-       pm_runtime_enable(&pdev->dev);
+       omap->usbhost_ick = clk_get(dev, "usbhost_ick");
+       if (IS_ERR(omap->usbhost_ick)) {
+               ret =  PTR_ERR(omap->usbhost_ick);
+               dev_err(dev, "usbhost_ick failed error:%d\n", ret);
+               goto err_end;
+       }
+
+       omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
+       if (IS_ERR(omap->usbhost_hs_fck)) {
+               ret = PTR_ERR(omap->usbhost_hs_fck);
+               dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
+               goto err_usbhost_ick;
+       }
+
+       omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
+       if (IS_ERR(omap->usbhost_fs_fck)) {
+               ret = PTR_ERR(omap->usbhost_fs_fck);
+               dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
+               goto err_usbhost_hs_fck;
+       }
+
+       omap->usbtll_fck = clk_get(dev, "usbtll_fck");
+       if (IS_ERR(omap->usbtll_fck)) {
+               ret = PTR_ERR(omap->usbtll_fck);
+               dev_err(dev, "usbtll_fck failed error:%d\n", ret);
+               goto err_usbhost_fs_fck;
+       }
+
+       omap->usbtll_ick = clk_get(dev, "usbtll_ick");
+       if (IS_ERR(omap->usbtll_ick)) {
+               ret = PTR_ERR(omap->usbtll_ick);
+               dev_err(dev, "usbtll_ick failed error:%d\n", ret);
+               goto err_usbtll_fck;
+       }
 
        omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
        if (IS_ERR(omap->utmi_p1_fck)) {
                ret = PTR_ERR(omap->utmi_p1_fck);
                dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
-               goto err_end;
+               goto err_usbtll_ick;
        }
 
        omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
@@ -485,8 +522,22 @@ err_xclk60mhsp1_ck:
 err_utmi_p1_fck:
        clk_put(omap->utmi_p1_fck);
 
+err_usbtll_ick:
+       clk_put(omap->usbtll_ick);
+
+err_usbtll_fck:
+       clk_put(omap->usbtll_fck);
+
+err_usbhost_fs_fck:
+       clk_put(omap->usbhost_fs_fck);
+
+err_usbhost_hs_fck:
+       clk_put(omap->usbhost_hs_fck);
+
+err_usbhost_ick:
+       clk_put(omap->usbhost_ick);
+
 err_end:
-       pm_runtime_disable(&pdev->dev);
        kfree(omap);
 
 end_probe:
@@ -520,7 +571,11 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
        clk_put(omap->utmi_p2_fck);
        clk_put(omap->xclk60mhsp1_ck);
        clk_put(omap->utmi_p1_fck);
-       pm_runtime_disable(&pdev->dev);
+       clk_put(omap->usbtll_ick);
+       clk_put(omap->usbtll_fck);
+       clk_put(omap->usbhost_fs_fck);
+       clk_put(omap->usbhost_hs_fck);
+       clk_put(omap->usbhost_ick);
        kfree(omap);
 
        return 0;
@@ -640,6 +695,7 @@ static int usbhs_enable(struct device *dev)
        struct usbhs_omap_platform_data *pdata = &omap->platdata;
        unsigned long                   flags = 0;
        int                             ret = 0;
+       unsigned long                   timeout;
        unsigned                        reg;
 
        dev_dbg(dev, "starting TI HSUSB Controller\n");
@@ -652,7 +708,11 @@ static int usbhs_enable(struct device *dev)
        if (omap->count > 0)
                goto end_count;
 
-       pm_runtime_get_sync(dev);
+       clk_enable(omap->usbhost_ick);
+       clk_enable(omap->usbhost_hs_fck);
+       clk_enable(omap->usbhost_fs_fck);
+       clk_enable(omap->usbtll_fck);
+       clk_enable(omap->usbtll_ick);
 
        if (pdata->ehci_data->phy_reset) {
                if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
@@ -676,6 +736,50 @@ static int usbhs_enable(struct device *dev)
        omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
        dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
 
+       /* perform TLL soft reset, and wait until reset is complete */
+       usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
+                       OMAP_USBTLL_SYSCONFIG_SOFTRESET);
+
+       /* Wait for TLL reset to complete */
+       timeout = jiffies + msecs_to_jiffies(1000);
+       while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
+                       & OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
+               cpu_relax();
+
+               if (time_after(jiffies, timeout)) {
+                       dev_dbg(dev, "operation timed out\n");
+                       ret = -EINVAL;
+                       goto err_tll;
+               }
+       }
+
+       dev_dbg(dev, "TLL RESET DONE\n");
+
+       /* (1<<3) = no idle mode only for initial debugging */
+       usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
+                       OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
+                       OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
+                       OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
+
+       /* Put UHH in NoIdle/NoStandby mode */
+       reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
+       if (is_omap_usbhs_rev1(omap)) {
+               reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
+                               | OMAP_UHH_SYSCONFIG_SIDLEMODE
+                               | OMAP_UHH_SYSCONFIG_CACTIVITY
+                               | OMAP_UHH_SYSCONFIG_MIDLEMODE);
+               reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
+
+
+       } else if (is_omap_usbhs_rev2(omap)) {
+               reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
+               reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
+               reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
+               reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
+       }
+
+       usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
+
        reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
        /* setup ULPI bypass and burst configurations */
        reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
@@ -815,8 +919,6 @@ end_count:
        return 0;
 
 err_tll:
-       pm_runtime_put_sync(dev);
-       spin_unlock_irqrestore(&omap->lock, flags);
        if (pdata->ehci_data->phy_reset) {
                if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
                        gpio_free(pdata->ehci_data->reset_gpio_port[0]);
@@ -824,6 +926,13 @@ err_tll:
                if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
                        gpio_free(pdata->ehci_data->reset_gpio_port[1]);
        }
+
+       clk_disable(omap->usbtll_ick);
+       clk_disable(omap->usbtll_fck);
+       clk_disable(omap->usbhost_fs_fck);
+       clk_disable(omap->usbhost_hs_fck);
+       clk_disable(omap->usbhost_ick);
+       spin_unlock_irqrestore(&omap->lock, flags);
        return ret;
 }
 
@@ -896,7 +1005,11 @@ static void usbhs_disable(struct device *dev)
                clk_disable(omap->utmi_p1_fck);
        }
 
-       pm_runtime_put_sync(dev);
+       clk_disable(omap->usbtll_ick);
+       clk_disable(omap->usbtll_fck);
+       clk_disable(omap->usbhost_fs_fck);
+       clk_disable(omap->usbhost_hs_fck);
+       clk_disable(omap->usbhost_ick);
 
        /* The gpio_free migh sleep; so unlock the spinlock */
        spin_unlock_irqrestore(&omap->lock, flags);
index 3d2dc56..283ac67 100644 (file)
@@ -125,7 +125,7 @@ static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL);
 static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
 {
        struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
-       struct tps65910_platform_data *pdata = dev_get_platdata(tps65910->dev);
+       struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
        int ret;
 
        ret = comp_threshold_set(tps65910, COMP1,  pdata->vmbch_threshold);
index 98517a3..e3bad82 100644 (file)
@@ -992,6 +992,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
         * features
         */
        dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
+       dev->vlan_features = dev->features;
 
        dev->irq = pdev->irq;
 
index 7d25a97..44e219c 100644 (file)
@@ -1111,7 +1111,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
                    struct bna_intr_info *intr_info)
 {
        int             err = 0;
-       unsigned long   flags;
+       unsigned long   irq_flags = 0, flags;
        u32     irq;
        irq_handler_t   irq_handler;
 
@@ -1125,18 +1125,17 @@ bnad_mbox_irq_alloc(struct bnad *bnad,
        if (bnad->cfg_flags & BNAD_CF_MSIX) {
                irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
                irq = bnad->msix_table[bnad->msix_num - 1].vector;
-               flags = 0;
                intr_info->intr_type = BNA_INTR_T_MSIX;
                intr_info->idl[0].vector = bnad->msix_num - 1;
        } else {
                irq_handler = (irq_handler_t)bnad_isr;
                irq = bnad->pcidev->irq;
-               flags = IRQF_SHARED;
+               irq_flags = IRQF_SHARED;
                intr_info->intr_type = BNA_INTR_T_INTX;
                /* intr_info->idl.vector = 0 ? */
        }
        spin_unlock_irqrestore(&bnad->bna_lock, flags);
-
+       flags = irq_flags;
        sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME);
 
        /*
index f181304..672f096 100644 (file)
@@ -1015,11 +1015,10 @@ static int greth_set_mac_add(struct net_device *dev, void *p)
                return -EINVAL;
 
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+       GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 |
+                     dev->dev_addr[4] << 8 | dev->dev_addr[5]);
 
-       GRETH_REGSAVE(regs->esa_msb, addr->sa_data[0] << 8 | addr->sa_data[1]);
-       GRETH_REGSAVE(regs->esa_lsb,
-                     addr->sa_data[2] << 24 | addr->
-                     sa_data[3] << 16 | addr->sa_data[4] << 8 | addr->sa_data[5]);
        return 0;
 }
 
index 3e5d0b6..0d28378 100644 (file)
@@ -692,10 +692,10 @@ static void sixpack_close(struct tty_struct *tty)
 {
        struct sixpack *sp;
 
-       write_lock(&disc_data_lock);
+       write_lock_bh(&disc_data_lock);
        sp = tty->disc_data;
        tty->disc_data = NULL;
-       write_unlock(&disc_data_lock);
+       write_unlock_bh(&disc_data_lock);
        if (!sp)
                return;
 
index 4c62839..bc02968 100644 (file)
@@ -813,10 +813,10 @@ static void mkiss_close(struct tty_struct *tty)
 {
        struct mkiss *ax;
 
-       write_lock(&disc_data_lock);
+       write_lock_bh(&disc_data_lock);
        ax = tty->disc_data;
        tty->disc_data = NULL;
-       write_unlock(&disc_data_lock);
+       write_unlock_bh(&disc_data_lock);
 
        if (!ax)
                return;
index b78be08..8f8b65a 100644 (file)
@@ -2360,7 +2360,8 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do)
                                        PCI_DMA_FROMDEVICE);
                        } else {
                                pci_unmap_single(np->pci_dev, np->rx_dma[entry],
-                                       buflen, PCI_DMA_FROMDEVICE);
+                                                buflen + NATSEMI_PADDING,
+                                                PCI_DMA_FROMDEVICE);
                                skb_put(skb = np->rx_skbuff[entry], pkt_len);
                                np->rx_skbuff[entry] = NULL;
                        }
index d328507..ca306fd 100644 (file)
@@ -16,7 +16,7 @@
  */
 #define DRV_NAME       "qlge"
 #define DRV_STRING     "QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION    "v1.00.00.27.00.00-01"
+#define DRV_VERSION    "v1.00.00.29.00.00-01"
 
 #define WQ_ADDR_ALIGN  0x3     /* 4 byte alignment */
 
@@ -1996,6 +1996,7 @@ enum {
        QL_LB_LINK_UP = 10,
        QL_FRC_COREDUMP = 11,
        QL_EEH_FATAL = 12,
+       QL_ASIC_RECOVERY = 14, /* We are in ascic recovery. */
 };
 
 /* link_status bit definitions */
index 930ae45..6b4ff97 100644 (file)
@@ -2152,6 +2152,10 @@ void ql_queue_asic_error(struct ql_adapter *qdev)
         * thread
         */
        clear_bit(QL_ADAPTER_UP, &qdev->flags);
+       /* Set asic recovery bit to indicate reset process that we are
+        * in fatal error recovery process rather than normal close
+        */
+       set_bit(QL_ASIC_RECOVERY, &qdev->flags);
        queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
 }
 
@@ -2166,23 +2170,20 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev,
                return;
 
        case CAM_LOOKUP_ERR_EVENT:
-               netif_err(qdev, link, qdev->ndev,
-                         "Multiple CAM hits lookup occurred.\n");
-               netif_err(qdev, drv, qdev->ndev,
-                         "This event shouldn't occur.\n");
+               netdev_err(qdev->ndev, "Multiple CAM hits lookup occurred.\n");
+               netdev_err(qdev->ndev, "This event shouldn't occur.\n");
                ql_queue_asic_error(qdev);
                return;
 
        case SOFT_ECC_ERROR_EVENT:
-               netif_err(qdev, rx_err, qdev->ndev,
-                         "Soft ECC error detected.\n");
+               netdev_err(qdev->ndev, "Soft ECC error detected.\n");
                ql_queue_asic_error(qdev);
                break;
 
        case PCI_ERR_ANON_BUF_RD:
-               netif_err(qdev, rx_err, qdev->ndev,
-                         "PCI error occurred when reading anonymous buffers from rx_ring %d.\n",
-                         ib_ae_rsp->q_id);
+               netdev_err(qdev->ndev, "PCI error occurred when reading "
+                                       "anonymous buffers from rx_ring %d.\n",
+                                       ib_ae_rsp->q_id);
                ql_queue_asic_error(qdev);
                break;
 
@@ -2437,11 +2438,10 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
         */
        if (var & STS_FE) {
                ql_queue_asic_error(qdev);
-               netif_err(qdev, intr, qdev->ndev,
-                         "Got fatal error, STS = %x.\n", var);
+               netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var);
                var = ql_read32(qdev, ERR_STS);
-               netif_err(qdev, intr, qdev->ndev,
-                         "Resetting chip. Error Status Register = 0x%x\n", var);
+               netdev_err(qdev->ndev, "Resetting chip. "
+                                       "Error Status Register = 0x%x\n", var);
                return IRQ_HANDLED;
        }
 
@@ -3818,11 +3818,17 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
        end_jiffies = jiffies +
                max((unsigned long)1, usecs_to_jiffies(30));
 
-       /* Stop management traffic. */
-       ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
+       /* Check if bit is set then skip the mailbox command and
+        * clear the bit, else we are in normal reset process.
+        */
+       if (!test_bit(QL_ASIC_RECOVERY, &qdev->flags)) {
+               /* Stop management traffic. */
+               ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
 
-       /* Wait for the NIC and MGMNT FIFOs to empty. */
-       ql_wait_fifo_empty(qdev);
+               /* Wait for the NIC and MGMNT FIFOs to empty. */
+               ql_wait_fifo_empty(qdev);
+       } else
+               clear_bit(QL_ASIC_RECOVERY, &qdev->flags);
 
        ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
 
index 8a72a97..1f3f7b4 100644 (file)
@@ -140,6 +140,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
        .tpauser        = 1,
        .hw_swap        = 1,
        .no_ade         = 1,
+       .rpadir         = 1,
+       .rpadir_value   = 2 << 16,
 };
 
 #define SH_GIGA_ETH_BASE       0xfee00000
@@ -1184,8 +1186,8 @@ static void sh_eth_adjust_link(struct net_device *ndev)
                                mdp->cd->set_rate(ndev);
                }
                if (mdp->link == PHY_DOWN) {
-                       sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF)
-                                       | ECMR_DM, ECMR);
+                       sh_eth_write(ndev,
+                               (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR);
                        new_state = 1;
                        mdp->link = phydev->link;
                }
index fa6e2ac..6740235 100644 (file)
@@ -575,7 +575,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
        struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
        u32 val;
 
-       while (num_allocated < num_to_alloc) {
+       while (num_allocated <= num_to_alloc) {
                struct vmxnet3_rx_buf_info *rbi;
                union Vmxnet3_GenericDesc *gd;
 
@@ -621,9 +621,15 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
 
                BUG_ON(rbi->dma_addr == 0);
                gd->rxd.addr = cpu_to_le64(rbi->dma_addr);
-               gd->dword[2] = cpu_to_le32((ring->gen << VMXNET3_RXD_GEN_SHIFT)
+               gd->dword[2] = cpu_to_le32((!ring->gen << VMXNET3_RXD_GEN_SHIFT)
                                           | val | rbi->len);
 
+               /* Fill the last buffer but dont mark it ready, or else the
+                * device will think that the queue is full */
+               if (num_allocated == num_to_alloc)
+                       break;
+
+               gd->dword[2] |= cpu_to_le32(ring->gen << VMXNET3_RXD_GEN_SHIFT);
                num_allocated++;
                vmxnet3_cmd_ring_adv_next2fill(ring);
        }
@@ -1140,6 +1146,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2
        };
        u32 num_rxd = 0;
+       bool skip_page_frags = false;
        struct Vmxnet3_RxCompDesc *rcd;
        struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
 #ifdef __BIG_ENDIAN_BITFIELD
@@ -1150,11 +1157,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                          &rxComp);
        while (rcd->gen == rq->comp_ring.gen) {
                struct vmxnet3_rx_buf_info *rbi;
-               struct sk_buff *skb;
+               struct sk_buff *skb, *new_skb = NULL;
+               struct page *new_page = NULL;
                int num_to_alloc;
                struct Vmxnet3_RxDesc *rxd;
                u32 idx, ring_idx;
-
+               struct vmxnet3_cmd_ring *ring = NULL;
                if (num_rxd >= quota) {
                        /* we may stop even before we see the EOP desc of
                         * the current pkt
@@ -1165,6 +1173,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2);
                idx = rcd->rxdIdx;
                ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1;
+               ring = rq->rx_ring + ring_idx;
                vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd,
                                  &rxCmdDesc);
                rbi = rq->buf_info[ring_idx] + idx;
@@ -1193,37 +1202,80 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                                goto rcd_done;
                        }
 
+                       skip_page_frags = false;
                        ctx->skb = rbi->skb;
-                       rbi->skb = NULL;
+                       new_skb = dev_alloc_skb(rbi->len + NET_IP_ALIGN);
+                       if (new_skb == NULL) {
+                               /* Skb allocation failed, do not handover this
+                                * skb to stack. Reuse it. Drop the existing pkt
+                                */
+                               rq->stats.rx_buf_alloc_failure++;
+                               ctx->skb = NULL;
+                               rq->stats.drop_total++;
+                               skip_page_frags = true;
+                               goto rcd_done;
+                       }
 
                        pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len,
                                         PCI_DMA_FROMDEVICE);
 
                        skb_put(ctx->skb, rcd->len);
+
+                       /* Immediate refill */
+                       new_skb->dev = adapter->netdev;
+                       skb_reserve(new_skb, NET_IP_ALIGN);
+                       rbi->skb = new_skb;
+                       rbi->dma_addr = pci_map_single(adapter->pdev,
+                                       rbi->skb->data, rbi->len,
+                                       PCI_DMA_FROMDEVICE);
+                       rxd->addr = cpu_to_le64(rbi->dma_addr);
+                       rxd->len = rbi->len;
+
                } else {
-                       BUG_ON(ctx->skb == NULL);
+                       BUG_ON(ctx->skb == NULL && !skip_page_frags);
+
                        /* non SOP buffer must be type 1 in most cases */
-                       if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) {
-                               BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
+                       BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE);
+                       BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
 
-                               if (rcd->len) {
-                                       pci_unmap_page(adapter->pdev,
-                                                      rbi->dma_addr, rbi->len,
-                                                      PCI_DMA_FROMDEVICE);
+                       /* If an sop buffer was dropped, skip all
+                        * following non-sop fragments. They will be reused.
+                        */
+                       if (skip_page_frags)
+                               goto rcd_done;
 
-                                       vmxnet3_append_frag(ctx->skb, rcd, rbi);
-                                       rbi->page = NULL;
-                               }
-                       } else {
-                               /*
-                                * The only time a non-SOP buffer is type 0 is
-                                * when it's EOP and error flag is raised, which
-                                * has already been handled.
+                       new_page = alloc_page(GFP_ATOMIC);
+                       if (unlikely(new_page == NULL)) {
+                               /* Replacement page frag could not be allocated.
+                                * Reuse this page. Drop the pkt and free the
+                                * skb which contained this page as a frag. Skip
+                                * processing all the following non-sop frags.
                                 */
-                               BUG_ON(true);
+                               rq->stats.rx_buf_alloc_failure++;
+                               dev_kfree_skb(ctx->skb);
+                               ctx->skb = NULL;
+                               skip_page_frags = true;
+                               goto rcd_done;
+                       }
+
+                       if (rcd->len) {
+                               pci_unmap_page(adapter->pdev,
+                                              rbi->dma_addr, rbi->len,
+                                              PCI_DMA_FROMDEVICE);
+
+                               vmxnet3_append_frag(ctx->skb, rcd, rbi);
                        }
+
+                       /* Immediate refill */
+                       rbi->page = new_page;
+                       rbi->dma_addr = pci_map_page(adapter->pdev, rbi->page,
+                                                    0, PAGE_SIZE,
+                                                    PCI_DMA_FROMDEVICE);
+                       rxd->addr = cpu_to_le64(rbi->dma_addr);
+                       rxd->len = rbi->len;
                }
 
+
                skb = ctx->skb;
                if (rcd->eop) {
                        skb->len += skb->data_len;
@@ -1244,26 +1296,27 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
                }
 
 rcd_done:
-               /* device may skip some rx descs */
-               rq->rx_ring[ring_idx].next2comp = idx;
-               VMXNET3_INC_RING_IDX_ONLY(rq->rx_ring[ring_idx].next2comp,
-                                         rq->rx_ring[ring_idx].size);
-
-               /* refill rx buffers frequently to avoid starving the h/w */
-               num_to_alloc = vmxnet3_cmd_ring_desc_avail(rq->rx_ring +
-                                                          ring_idx);
-               if (unlikely(num_to_alloc > VMXNET3_RX_ALLOC_THRESHOLD(rq,
-                                                       ring_idx, adapter))) {
-                       vmxnet3_rq_alloc_rx_buf(rq, ring_idx, num_to_alloc,
-                                               adapter);
-
-                       /* if needed, update the register */
-                       if (unlikely(rq->shared->updateRxProd)) {
-                               VMXNET3_WRITE_BAR0_REG(adapter,
-                                       rxprod_reg[ring_idx] + rq->qid * 8,
-                                       rq->rx_ring[ring_idx].next2fill);
-                               rq->uncommitted[ring_idx] = 0;
-                       }
+               /* device may have skipped some rx descs */
+               ring->next2comp = idx;
+               num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring);
+               ring = rq->rx_ring + ring_idx;
+               while (num_to_alloc) {
+                       vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd,
+                                         &rxCmdDesc);
+                       BUG_ON(!rxd->addr);
+
+                       /* Recv desc is ready to be used by the device */
+                       rxd->gen = ring->gen;
+                       vmxnet3_cmd_ring_adv_next2fill(ring);
+                       num_to_alloc--;
+               }
+
+               /* if needed, update the register */
+               if (unlikely(rq->shared->updateRxProd)) {
+                       VMXNET3_WRITE_BAR0_REG(adapter,
+                               rxprod_reg[ring_idx] + rq->qid * 8,
+                               ring->next2fill);
+                       rq->uncommitted[ring_idx] = 0;
                }
 
                vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
@@ -2894,6 +2947,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
        else
 #endif
                num_rx_queues = 1;
+       num_rx_queues = rounddown_pow_of_two(num_rx_queues);
 
        if (enable_mq)
                num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES,
@@ -2901,6 +2955,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
        else
                num_tx_queues = 1;
 
+       num_tx_queues = rounddown_pow_of_two(num_tx_queues);
        netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter),
                                   max(num_tx_queues, num_rx_queues));
        printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n",
@@ -3085,6 +3140,7 @@ vmxnet3_remove_device(struct pci_dev *pdev)
        else
 #endif
                num_rx_queues = 1;
+       num_rx_queues = rounddown_pow_of_two(num_rx_queues);
 
        cancel_work_sync(&adapter->work);
 
index f50d36f..e08d75e 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/if_vlan.h>
 #include <linux/if_arp.h>
 #include <linux/inetdevice.h>
+#include <linux/log2.h>
 
 #include "vmxnet3_defs.h"
 
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.1.9.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.1.18.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01010900
+#define VMXNET3_DRIVER_VERSION_NUM      0x01011200
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index 1fef84f..392771f 100644 (file)
@@ -691,14 +691,12 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
                if (!chinfo[pier].pd_curves)
                        continue;
 
-               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+               for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
                        struct ath5k_pdgain_info *pd =
                                        &chinfo[pier].pd_curves[pdg];
 
-                       if (pd != NULL) {
-                               kfree(pd->pd_step);
-                               kfree(pd->pd_pwr);
-                       }
+                       kfree(pd->pd_step);
+                       kfree(pd->pd_pwr);
                }
 
                kfree(chinfo[pier].pd_curves);
index b8cbfc7..3bad0b2 100644 (file)
@@ -278,6 +278,12 @@ static int ath_pci_suspend(struct device *device)
 
        ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 
+       /* The device has to be moved to FULLSLEEP forcibly.
+        * Otherwise the chip never moved to full sleep,
+        * when no interface is up.
+        */
+       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
+
        return 0;
 }
 
index 61d4a11..2a88e73 100644 (file)
@@ -36,6 +36,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL100_UCODE_API_MIN 5
 
 #define IWL1000_FW_PRE "iwlwifi-1000-"
-#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
+#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL100_FW_PRE "iwlwifi-100-"
-#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode"
+#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode"
 
 
 /*
index 2282279..3df76f5 100644 (file)
@@ -36,6 +36,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL105_UCODE_API_MIN 5
 
 #define IWL2030_FW_PRE "iwlwifi-2030-"
-#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
+#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode"
 
 #define IWL2000_FW_PRE "iwlwifi-2000-"
-#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
+#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL105_FW_PRE "iwlwifi-105-"
-#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode"
+#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode"
 
 static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
 {
index f99f9c1..e816c27 100644 (file)
@@ -37,6 +37,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL5150_UCODE_API_MIN 1
 
 #define IWL5000_FW_PRE "iwlwifi-5000-"
-#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
+#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL5150_FW_PRE "iwlwifi-5150-"
-#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
+#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode"
 
 /* NIC configuration for 5000 series */
 static void iwl5000_nic_config(struct iwl_priv *priv)