Merge branch 'gpio/merge' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Jul 2011 16:01:11 +0000 (09:01 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Jul 2011 16:01:11 +0000 (09:01 -0700)
* 'gpio/merge' of git://git.secretlab.ca/git/linux-2.6:
  gpio/langwell_gpio: ack the correct bit for langwell gpio interrupts

135 files changed:
Documentation/CodingStyle
Documentation/cgroups/blkio-controller.txt
Documentation/filesystems/caching/netfs-api.txt
MAINTAINERS
arch/arm/mach-omap1/board-ams-delta.c
arch/arm/mach-omap1/gpio15xx.c
arch/arm/mach-omap1/gpio16xx.c
arch/arm/mach-omap1/gpio7xx.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/x86/include/asm/mmzone_32.h
arch/x86/kernel/acpi/realmode/wakeup.S
arch/x86/kernel/acpi/realmode/wakeup.h
arch/x86/kernel/acpi/sleep.c
arch/x86/kernel/reboot.c
arch/x86/oprofile/nmi_int.c
arch/x86/pci/xen.c
arch/x86/platform/efi/efi.c
block/cfq-iosched.c
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_bitmap.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/rv770.c
drivers/i2c/busses/i2c-bfin-twi.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-tegra.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/staging/lirc/lirc_imon.c
drivers/staging/lirc/lirc_serial.c
drivers/staging/lirc/lirc_sir.c
drivers/staging/lirc/lirc_zilog.c
drivers/usb/core/message.c
drivers/usb/gadget/fsl_udc_core.c
fs/binfmt_elf_fdpic.c
fs/ceph/file.c
fs/cifs/fscache.c
fs/fscache/page.c
fs/hfsplus/super.c
fs/hfsplus/wrapper.c
fs/locks.c
fs/nfs/fscache.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_trans.c
include/linux/drbd_limits.h
include/linux/fscache.h
include/linux/sched.h
include/media/lirc_dev.h
include/media/m5mols.h
include/net/cfg80211.h
include/net/dst.h
kernel/jump_label.c
kernel/power/snapshot.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

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 a167ab8..7cc6bf2 100644 (file)
@@ -673,6 +673,22 @@ storage request to complete, or it may attempt to cancel the storage request -
 in which case the page will not be stored in the cache this time.
 
 
+BULK INODE PAGE UNCACHE
+-----------------------
+
+A convenience routine is provided to perform an uncache on all the pages
+attached to an inode.  This assumes that the pages on the inode correspond on a
+1:1 basis with the pages in the cache.
+
+       void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
+                                            struct inode *inode);
+
+This takes the netfs cookie that the pages were cached with and the inode that
+the pages are attached to.  This function will wait for pages to finish being
+written to the cache and for the cache to finish with the page generally.  No
+error is returned.
+
+
 ==========================
 INDEX AND DATA FILE UPDATE
 ==========================
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 de88c92..f49ce85 100644 (file)
@@ -215,7 +215,7 @@ static struct omap_kp_platform_data ams_delta_kp_data __initdata = {
        .delay          = 9,
 };
 
-static struct platform_device ams_delta_kp_device __initdata = {
+static struct platform_device ams_delta_kp_device = {
        .name           = "omap-keypad",
        .id             = -1,
        .dev            = {
@@ -225,12 +225,12 @@ static struct platform_device ams_delta_kp_device __initdata = {
        .resource       = ams_delta_kp_resources,
 };
 
-static struct platform_device ams_delta_lcd_device __initdata = {
+static struct platform_device ams_delta_lcd_device = {
        .name   = "lcd_ams_delta",
        .id     = -1,
 };
 
-static struct platform_device ams_delta_led_device __initdata = {
+static struct platform_device ams_delta_led_device = {
        .name   = "ams-delta-led",
        .id     = -1
 };
@@ -267,7 +267,7 @@ static struct soc_camera_link ams_delta_iclink = {
        .power          = ams_delta_camera_power,
 };
 
-static struct platform_device ams_delta_camera_device __initdata = {
+static struct platform_device ams_delta_camera_device = {
        .name   = "soc-camera-pdrv",
        .id     = 0,
        .dev    = {
index 04c4b04..364137c 100644 (file)
@@ -41,7 +41,7 @@ static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
        .bank_stride            = 1,
 };
 
-static struct __initdata platform_device omap15xx_mpu_gpio = {
+static struct platform_device omap15xx_mpu_gpio = {
        .name           = "omap_gpio",
        .id             = 0,
        .dev            = {
@@ -70,7 +70,7 @@ static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap15xx_gpio = {
+static struct platform_device omap15xx_gpio = {
        .name           = "omap_gpio",
        .id             = 1,
        .dev            = {
index 5dd0d4c..293a246 100644 (file)
@@ -44,7 +44,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
        .bank_stride            = 1,
 };
 
-static struct __initdata platform_device omap16xx_mpu_gpio = {
+static struct platform_device omap16xx_mpu_gpio = {
        .name           = "omap_gpio",
        .id             = 0,
        .dev            = {
@@ -73,7 +73,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio1 = {
+static struct platform_device omap16xx_gpio1 = {
        .name           = "omap_gpio",
        .id             = 1,
        .dev            = {
@@ -102,7 +102,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio2 = {
+static struct platform_device omap16xx_gpio2 = {
        .name           = "omap_gpio",
        .id             = 2,
        .dev            = {
@@ -131,7 +131,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio3 = {
+static struct platform_device omap16xx_gpio3 = {
        .name           = "omap_gpio",
        .id             = 3,
        .dev            = {
@@ -160,7 +160,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
        .bank_width             = 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio4 = {
+static struct platform_device omap16xx_gpio4 = {
        .name           = "omap_gpio",
        .id             = 4,
        .dev            = {
index 1204c8b..c6ad248 100644 (file)
@@ -46,7 +46,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
        .bank_stride            = 2,
 };
 
-static struct __initdata platform_device omap7xx_mpu_gpio = {
+static struct platform_device omap7xx_mpu_gpio = {
        .name           = "omap_gpio",
        .id             = 0,
        .dev            = {
@@ -75,7 +75,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio1 = {
+static struct platform_device omap7xx_gpio1 = {
        .name           = "omap_gpio",
        .id             = 1,
        .dev            = {
@@ -104,7 +104,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio2 = {
+static struct platform_device omap7xx_gpio2 = {
        .name           = "omap_gpio",
        .id             = 2,
        .dev            = {
@@ -133,7 +133,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio3 = {
+static struct platform_device omap7xx_gpio3 = {
        .name           = "omap_gpio",
        .id             = 3,
        .dev            = {
@@ -162,7 +162,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio4 = {
+static struct platform_device omap7xx_gpio4 = {
        .name           = "omap_gpio",
        .id             = 4,
        .dev            = {
@@ -191,7 +191,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio5 = {
+static struct platform_device omap7xx_gpio5 = {
        .name           = "omap_gpio",
        .id             = 5,
        .dev            = {
@@ -220,7 +220,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
        .bank_width             = 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio6 = {
+static struct platform_device omap7xx_gpio6 = {
        .name           = "omap_gpio",
        .id             = 6,
        .dev            = {
index 9903667..88bd6f7 100644 (file)
@@ -558,7 +558,7 @@ static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module =
        .subdev_board_info = &rx51_si4713_board_info,
 };
 
-static struct platform_device rx51_si4713_dev __initdata_or_module = {
+static struct platform_device rx51_si4713_dev = {
        .name   = "radio-si4713",
        .id     = -1,
        .dev    = {
index 224e8c5..ffa037f 100644 (file)
@@ -57,6 +57,8 @@ static inline int pfn_valid(int pfn)
        return 0;
 }
 
+#define early_pfn_valid(pfn)   pfn_valid((pfn))
+
 #endif /* CONFIG_DISCONTIGMEM */
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
index ead21b6..b4fd836 100644 (file)
@@ -28,6 +28,8 @@ pmode_cr3:    .long   0       /* Saved %cr3 */
 pmode_cr4:     .long   0       /* Saved %cr4 */
 pmode_efer:    .quad   0       /* Saved EFER */
 pmode_gdt:     .quad   0
+pmode_misc_en: .quad   0       /* Saved MISC_ENABLE MSR */
+pmode_behavior:        .long   0       /* Wakeup behavior flags */
 realmode_flags:        .long   0
 real_magic:    .long   0
 trampoline_segment:    .word 0
@@ -91,6 +93,18 @@ wakeup_code:
        /* Call the C code */
        calll   main
 
+       /* Restore MISC_ENABLE before entering protected mode, in case
+          BIOS decided to clear XD_DISABLE during S3. */
+       movl    pmode_behavior, %eax
+       btl     $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax
+       jnc     1f
+
+       movl    pmode_misc_en, %eax
+       movl    pmode_misc_en + 4, %edx
+       movl    $MSR_IA32_MISC_ENABLE, %ecx
+       wrmsr
+1:
+
        /* Do any other stuff... */
 
 #ifndef CONFIG_64BIT
index e1828c0..97a29e1 100644 (file)
@@ -21,6 +21,9 @@ struct wakeup_header {
        u32 pmode_efer_low;     /* Protected mode EFER */
        u32 pmode_efer_high;
        u64 pmode_gdt;
+       u32 pmode_misc_en_low;  /* Protected mode MISC_ENABLE */
+       u32 pmode_misc_en_high;
+       u32 pmode_behavior;     /* Wakeup routine behavior flags */
        u32 realmode_flags;
        u32 real_magic;
        u16 trampoline_segment; /* segment with trampoline code, 64-bit only */
@@ -39,4 +42,7 @@ extern struct wakeup_header wakeup_header;
 #define WAKEUP_HEADER_SIGNATURE 0x51ee1111
 #define WAKEUP_END_SIGNATURE   0x65a22c82
 
+/* Wakeup behavior bits */
+#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE     0
+
 #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
index 18a857b..103b6ab 100644 (file)
@@ -77,6 +77,12 @@ int acpi_suspend_lowlevel(void)
 
        header->pmode_cr0 = read_cr0();
        header->pmode_cr4 = read_cr4_safe();
+       header->pmode_behavior = 0;
+       if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
+                       &header->pmode_misc_en_low,
+                       &header->pmode_misc_en_high))
+               header->pmode_behavior |=
+                       (1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
        header->realmode_flags = acpi_realmode_flags;
        header->real_magic = 0x12345678;
 
index 0c016f7..4f0d46f 100644 (file)
@@ -294,6 +294,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
                },
        },
+       { /* Handle reboot issue on Acer Aspire one */
+               .callback = set_bios_reboot,
+               .ident = "Acer Aspire One A110",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+               },
+       },
        { }
 };
 
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 fe00830..f567965 100644 (file)
@@ -327,13 +327,12 @@ int __init pci_xen_hvm_init(void)
 }
 
 #ifdef CONFIG_XEN_DOM0
-static int xen_register_pirq(u32 gsi, int triggering)
+static int xen_register_pirq(u32 gsi, int gsi_override, int triggering)
 {
        int rc, pirq, irq = -1;
        struct physdev_map_pirq map_irq;
        int shareable = 0;
        char *name;
-       bool gsi_override = false;
 
        if (!xen_pv_domain())
                return -1;
@@ -345,31 +344,12 @@ static int xen_register_pirq(u32 gsi, int triggering)
                shareable = 1;
                name = "ioapic-level";
        }
-
        pirq = xen_allocate_pirq_gsi(gsi);
        if (pirq < 0)
                goto out;
 
-       /* 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);
+       if (gsi_override >= 0)
+               irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name);
        else
                irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
        if (irq < 0)
@@ -392,7 +372,7 @@ out:
        return irq;
 }
 
-static int xen_register_gsi(u32 gsi, int triggering, int polarity)
+static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity)
 {
        int rc, irq;
        struct physdev_setup_gsi setup_gsi;
@@ -403,7 +383,7 @@ static int xen_register_gsi(u32 gsi, int triggering, int polarity)
        printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n",
                        gsi, triggering, polarity);
 
-       irq = xen_register_pirq(gsi, triggering);
+       irq = xen_register_pirq(gsi, gsi_override, triggering);
 
        setup_gsi.gsi = gsi;
        setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1);
@@ -425,6 +405,8 @@ static __init void xen_setup_acpi_sci(void)
        int rc;
        int trigger, polarity;
        int gsi = acpi_sci_override_gsi;
+       int irq = -1;
+       int gsi_override = -1;
 
        if (!gsi)
                return;
@@ -441,7 +423,25 @@ static __init void xen_setup_acpi_sci(void)
        printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d "
                        "polarity=%d\n", gsi, trigger, polarity);
 
-       gsi = xen_register_gsi(gsi, trigger, polarity);
+       /* 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).
+        */
+       /* Check whether the GSI != IRQ */
+       if (acpi_gsi_to_irq(gsi, &irq) == 0) {
+               if (irq >= 0 && irq != gsi)
+                       /* Bugger, we MUST have that IRQ. */
+                       gsi_override = irq;
+       }
+
+       gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity);
        printk(KERN_INFO "xen: acpi sci %d\n", gsi);
 
        return;
@@ -450,7 +450,7 @@ static __init void xen_setup_acpi_sci(void)
 static int acpi_register_gsi_xen(struct device *dev, u32 gsi,
                                 int trigger, int polarity)
 {
-       return xen_register_gsi(gsi, trigger, polarity);
+       return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity);
 }
 
 static int __init pci_xen_initial_domain(void)
@@ -489,7 +489,7 @@ void __init xen_setup_pirqs(void)
                if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)
                        continue;
 
-               xen_register_pirq(irq,
+               xen_register_pirq(irq, -1 /* no GSI override */,
                        trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE);
        }
 }
index 474356b..899e393 100644 (file)
@@ -504,9 +504,6 @@ void __init efi_init(void)
        x86_platform.set_wallclock = efi_set_rtc_mmss;
 #endif
 
-       /* Setup for EFI runtime service */
-       reboot_type = BOOT_EFI;
-
 #if EFI_DEBUG
        print_efi_memmap();
 #endif
index f379943..ae21919 100644 (file)
@@ -2773,11 +2773,14 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
        smp_wmb();
        cic->key = cfqd_dead_key(cfqd);
 
+       rcu_read_lock();
        if (rcu_dereference(ioc->ioc_data) == cic) {
+               rcu_read_unlock();
                spin_lock(&ioc->lock);
                rcu_assign_pointer(ioc->ioc_data, NULL);
                spin_unlock(&ioc->lock);
-       }
+       } else
+               rcu_read_unlock();
 
        if (cic->cfqq[BLK_RW_ASYNC]) {
                cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]);
@@ -3084,7 +3087,8 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
 
        spin_lock_irqsave(&ioc->lock, flags);
 
-       BUG_ON(ioc->ioc_data == cic);
+       BUG_ON(rcu_dereference_check(ioc->ioc_data,
+               lockdep_is_held(&ioc->lock)) == cic);
 
        radix_tree_delete(&ioc->radix_root, cfqd->cic_index);
        hlist_del_rcu(&cic->cic_list);
index 09ef9a8..cf0e63d 100644 (file)
@@ -79,7 +79,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev,
        md_io.error = 0;
 
        if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags))
-               rw |= REQ_FUA;
+               rw |= REQ_FUA | REQ_FLUSH;
        rw |= REQ_SYNC;
 
        bio = bio_alloc(GFP_NOIO, 1);
index f440a02..7b97629 100644 (file)
@@ -112,9 +112,6 @@ struct drbd_bitmap {
        struct task_struct *bm_task;
 };
 
-static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
-                              unsigned long e, int val, const enum km_type km);
-
 #define bm_print_lock_info(m) __bm_print_lock_info(m, __func__)
 static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
 {
@@ -994,6 +991,9 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
                bio_endio(bio, -EIO);
        } else {
                submit_bio(rw, bio);
+               /* this should not count as user activity and cause the
+                * resync to throttle -- see drbd_rs_should_slow_down(). */
+               atomic_add(len >> 9, &mdev->rs_sect_ev);
        }
 }
 
@@ -1256,7 +1256,7 @@ unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_f
  * expected to be called for only a few bits (e - s about BITS_PER_LONG).
  * Must hold bitmap lock already. */
 static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
-       unsigned long e, int val, const enum km_type km)
+       unsigned long e, int val)
 {
        struct drbd_bitmap *b = mdev->bitmap;
        unsigned long *p_addr = NULL;
@@ -1274,14 +1274,14 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
                unsigned int page_nr = bm_bit_to_page_idx(b, bitnr);
                if (page_nr != last_page_nr) {
                        if (p_addr)
-                               __bm_unmap(p_addr, km);
+                               __bm_unmap(p_addr, KM_IRQ1);
                        if (c < 0)
                                bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
                        else if (c > 0)
                                bm_set_page_need_writeout(b->bm_pages[last_page_nr]);
                        changed_total += c;
                        c = 0;
-                       p_addr = __bm_map_pidx(b, page_nr, km);
+                       p_addr = __bm_map_pidx(b, page_nr, KM_IRQ1);
                        last_page_nr = page_nr;
                }
                if (val)
@@ -1290,7 +1290,7 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
                        c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr));
        }
        if (p_addr)
-               __bm_unmap(p_addr, km);
+               __bm_unmap(p_addr, KM_IRQ1);
        if (c < 0)
                bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
        else if (c > 0)
@@ -1318,7 +1318,7 @@ static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
        if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags)
                bm_print_lock_info(mdev);
 
-       c = __bm_change_bits_to(mdev, s, e, val, KM_IRQ1);
+       c = __bm_change_bits_to(mdev, s, e, val);
 
        spin_unlock_irqrestore(&b->bm_lock, flags);
        return c;
@@ -1343,16 +1343,17 @@ static inline void bm_set_full_words_within_one_page(struct drbd_bitmap *b,
 {
        int i;
        int bits;
-       unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_USER0);
+       unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_IRQ1);
        for (i = first_word; i < last_word; i++) {
                bits = hweight_long(paddr[i]);
                paddr[i] = ~0UL;
                b->bm_set += BITS_PER_LONG - bits;
        }
-       kunmap_atomic(paddr, KM_USER0);
+       kunmap_atomic(paddr, KM_IRQ1);
 }
 
-/* Same thing as drbd_bm_set_bits, but without taking the spin_lock_irqsave.
+/* Same thing as drbd_bm_set_bits,
+ * but more efficient for a large bit range.
  * You must first drbd_bm_lock().
  * Can be called to set the whole bitmap in one go.
  * Sets bits from s to e _inclusive_. */
@@ -1366,6 +1367,7 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
         * Do not use memset, because we must account for changes,
         * so we need to loop over the words with hweight() anyways.
         */
+       struct drbd_bitmap *b = mdev->bitmap;
        unsigned long sl = ALIGN(s,BITS_PER_LONG);
        unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1);
        int first_page;
@@ -1376,15 +1378,19 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
 
        if (e - s <= 3*BITS_PER_LONG) {
                /* don't bother; el and sl may even be wrong. */
-               __bm_change_bits_to(mdev, s, e, 1, KM_USER0);
+               spin_lock_irq(&b->bm_lock);
+               __bm_change_bits_to(mdev, s, e, 1);
+               spin_unlock_irq(&b->bm_lock);
                return;
        }
 
        /* difference is large enough that we can trust sl and el */
 
+       spin_lock_irq(&b->bm_lock);
+
        /* bits filling the current long */
        if (sl)
-               __bm_change_bits_to(mdev, s, sl-1, 1, KM_USER0);
+               __bm_change_bits_to(mdev, s, sl-1, 1);
 
        first_page = sl >> (3 + PAGE_SHIFT);
        last_page = el >> (3 + PAGE_SHIFT);
@@ -1397,8 +1403,10 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
        /* first and full pages, unless first page == last page */
        for (page_nr = first_page; page_nr < last_page; page_nr++) {
                bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word);
+               spin_unlock_irq(&b->bm_lock);
                cond_resched();
                first_word = 0;
+               spin_lock_irq(&b->bm_lock);
        }
 
        /* last page (respectively only page, for first page == last page) */
@@ -1411,7 +1419,8 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
         * it would trigger an assert in __bm_change_bits_to()
         */
        if (el <= e)
-               __bm_change_bits_to(mdev, el, e, 1, KM_USER0);
+               __bm_change_bits_to(mdev, el, e, 1);
+       spin_unlock_irq(&b->bm_lock);
 }
 
 /* returns bit state
index 25d32c5..43beaca 100644 (file)
@@ -4602,6 +4602,11 @@ int drbd_asender(struct drbd_thread *thi)
                        dev_err(DEV, "meta connection shut down by peer.\n");
                        goto reconnect;
                } else if (rv == -EAGAIN) {
+                       /* If the data socket received something meanwhile,
+                        * that is good enough: peer is still alive. */
+                       if (time_after(mdev->last_received,
+                               jiffies - mdev->meta.socket->sk->sk_rcvtimeo))
+                               continue;
                        if (ping_timeout_active) {
                                dev_err(DEV, "PingAck did not arrive in time.\n");
                                goto reconnect;
@@ -4637,6 +4642,7 @@ int drbd_asender(struct drbd_thread *thi)
                                goto reconnect;
                }
                if (received == expect) {
+                       mdev->last_received = jiffies;
                        D_ASSERT(cmd != NULL);
                        if (!cmd->process(mdev, h))
                                goto reconnect;
index 4d76b06..4d3e6f6 100644 (file)
@@ -536,12 +536,7 @@ static int w_make_resync_request(struct drbd_conf *mdev,
                return 1;
        }
 
-       /* starting with drbd 8.3.8, we can handle multi-bio EEs,
-        * if it should be necessary */
-       max_bio_size =
-               mdev->agreed_pro_version < 94 ? queue_max_hw_sectors(mdev->rq_queue) << 9 :
-               mdev->agreed_pro_version < 95 ? DRBD_MAX_SIZE_H80_PACKET : DRBD_MAX_BIO_SIZE;
-
+       max_bio_size = queue_max_hw_sectors(mdev->rq_queue) << 9;
        number = drbd_rs_number_requests(mdev);
        if (number == 0)
                goto requeue;
index 21058e6..82db185 100644 (file)
@@ -886,9 +886,6 @@ int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
        total_objects += dev->mode_config.num_connector;
        total_objects += dev->mode_config.num_encoder;
 
-       if (total_objects == 0)
-               return -EINVAL;
-
        group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
        if (!group->id_list)
                return -ENOMEM;
index e8a5ffb..a2d9008 100644 (file)
@@ -3237,6 +3237,7 @@ void evergreen_fini(struct radeon_device *rdev)
        r700_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        evergreen_pcie_gart_fini(rdev);
        radeon_gem_fini(rdev);
index 1636e34..b7b2714 100644 (file)
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
 #       define LB_D5_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD5_INTERRUPT                        (1 << 17)
 #       define DC_HPD5_RX_INTERRUPT                     (1 << 18)
-#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6050
+#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6150
 #       define LB_D6_VLINE_INTERRUPT                    (1 << 2)
 #       define LB_D6_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD6_INTERRUPT                        (1 << 17)
index 16caafe..559dbd4 100644 (file)
@@ -1581,6 +1581,7 @@ void cayman_fini(struct radeon_device *rdev)
        cayman_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        cayman_pcie_gart_fini(rdev);
        radeon_gem_fini(rdev);
index f79d2cc..bc54b26 100644 (file)
@@ -2628,6 +2628,7 @@ void r600_fini(struct radeon_device *rdev)
        r600_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        r600_pcie_gart_fini(rdev);
        radeon_agp_fini(rdev);
index f140a0d..0245ae6 100644 (file)
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
index 8bb347d..4de5189 100644 (file)
@@ -1368,6 +1368,7 @@ void rv770_fini(struct radeon_device *rdev)
        r700_cp_fini(rdev);
        r600_irq_fini(rdev);
        radeon_wb_fini(rdev);
+       radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        rv770_pcie_gart_fini(rdev);
        rv770_vram_scratch_fini(rdev);
index 52b545a..cbc98ae 100644 (file)
@@ -193,7 +193,13 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,
                return;
        }
        if (twi_int_status & MCOMP) {
-               if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+               if ((read_MASTER_CTL(iface) & MEN) == 0 &&
+                       (iface->cur_mode == TWI_I2C_MODE_REPEAT ||
+                       iface->cur_mode == TWI_I2C_MODE_COMBINED)) {
+                       iface->result = -1;
+                       write_INT_MASK(iface, 0);
+                       write_MASTER_CTL(iface, 0);
+               } else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
                        if (iface->readNum == 0) {
                                /* set the read number to 1 and ask for manual
                                 * stop in block combine mode
index 6c00c10..f84a63c 100644 (file)
@@ -248,12 +248,12 @@ static inline int is_msgend(struct s3c24xx_i2c *i2c)
        return i2c->msg_ptr >= i2c->msg->len;
 }
 
-/* i2s_s3c_irq_nextbyte
+/* i2c_s3c_irq_nextbyte
  *
  * process an interrupt and work out what to do
  */
 
-static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
+static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
 {
        unsigned long tmp;
        unsigned char byte;
@@ -264,7 +264,6 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
        case STATE_IDLE:
                dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
                goto out;
-               break;
 
        case STATE_STOP:
                dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
@@ -444,7 +443,7 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
        /* pretty much this leaves us with the fact that we've
         * transmitted or received whatever byte we last sent */
 
-       i2s_s3c_irq_nextbyte(i2c, status);
+       i2c_s3c_irq_nextbyte(i2c, status);
 
  out:
        return IRQ_HANDLED;
index 4d93196..fb3b4f8 100644 (file)
 #define I2C_CNFG_NEW_MASTER_FSM                        (1<<11)
 #define I2C_STATUS                             0x01C
 #define I2C_SL_CNFG                            0x020
+#define I2C_SL_CNFG_NACK                       (1<<1)
 #define I2C_SL_CNFG_NEWSL                      (1<<2)
 #define I2C_SL_ADDR1                           0x02c
+#define I2C_SL_ADDR2                           0x030
 #define I2C_TX_FIFO                            0x050
 #define I2C_RX_FIFO                            0x054
 #define I2C_PACKET_TRANSFER_STATUS             0x058
@@ -337,7 +339,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 
        if (!i2c_dev->is_dvc) {
                u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
-               i2c_writel(i2c_dev, sl_cfg | I2C_SL_CNFG_NEWSL, I2C_SL_CNFG);
+               sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
+               i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
+               i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
+               i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
+
        }
 
        val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
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)
index fbe565c..5b150bc 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 IWL6000G2_UCODE_API_MIN 4
 
 #define IWL6000_FW_PRE "iwlwifi-6000-"
-#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
+#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode"
 
 #define IWL6050_FW_PRE "iwlwifi-6050-"
-#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
+#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode"
 
 #define IWL6005_FW_PRE "iwlwifi-6000g2a-"
-#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode"
+#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode"
 
 #define IWL6030_FW_PRE "iwlwifi-6000g2b-"
-#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode"
+#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
 
 static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
 {
index 213c80c..45cc51c 100644 (file)
@@ -1763,6 +1763,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
        struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_context *tmp;
+       enum nl80211_iftype newviftype = newtype;
        u32 interface_modes;
        int err;
 
@@ -1818,7 +1819,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
        /* success */
        iwl_teardown_interface(priv, vif, true);
-       vif->type = newtype;
+       vif->type = newviftype;
        vif->p2p = newp2p;
        err = iwl_setup_interface(priv, ctx);
        WARN_ON(err);
index 686e176..137dba9 100644 (file)
@@ -126,7 +126,7 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
 }
 
 static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
-                            struct iwl_tfd *tfd)
+                            struct iwl_tfd *tfd, int dma_dir)
 {
        struct pci_dev *dev = priv->pci_dev;
        int i;
@@ -151,7 +151,7 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
        /* Unmap chunks, if any. */
        for (i = 1; i < num_tbs; i++)
                pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
-                               iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
+                               iwl_tfd_tb_get_len(tfd, i), dma_dir);
 }
 
 /**
@@ -167,7 +167,8 @@ void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
        struct iwl_tfd *tfd_tmp = txq->tfds;
        int index = txq->q.read_ptr;
 
-       iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index]);
+       iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index],
+                        PCI_DMA_TODEVICE);
 
        /* free SKB */
        if (txq->txb) {
@@ -310,9 +311,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv)
                i = get_cmd_index(q, q->read_ptr);
 
                if (txq->meta[i].flags & CMD_MAPPED) {
-                       pci_unmap_single(priv->pci_dev,
-                                        dma_unmap_addr(&txq->meta[i], mapping),
-                                        dma_unmap_len(&txq->meta[i], len),
+                       iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i],
                                         PCI_DMA_BIDIRECTIONAL);
                        txq->meta[i].flags = 0;
                }
@@ -535,12 +534,7 @@ out_free_arrays:
 void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                        int slots_num, u32 txq_id)
 {
-       int actual_slots = slots_num;
-
-       if (txq_id == priv->cmd_queue)
-               actual_slots++;
-
-       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * slots_num);
 
        txq->need_update = 0;
 
@@ -700,10 +694,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
                if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
                        continue;
                phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i],
-                                          cmd->len[i], PCI_DMA_TODEVICE);
+                                          cmd->len[i], PCI_DMA_BIDIRECTIONAL);
                if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) {
                        iwlagn_unmap_tfd(priv, out_meta,
-                                        &txq->tfds[q->write_ptr]);
+                                        &txq->tfds[q->write_ptr],
+                                        PCI_DMA_BIDIRECTIONAL);
                        idx = -ENOMEM;
                        goto out;
                }
@@ -807,7 +802,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        cmd = txq->cmd[cmd_index];
        meta = &txq->meta[cmd_index];
 
-       iwlagn_unmap_tfd(priv, meta, &txq->tfds[index]);
+       iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], PCI_DMA_BIDIRECTIONAL);
 
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
index 4039eda..4a9e563 100644 (file)
@@ -672,8 +672,6 @@ static void imon_incoming_packet(struct imon_context *context,
 static void usb_rx_callback(struct urb *urb)
 {
        struct imon_context *context;
-       unsigned char *buf;
-       int len;
        int intfnum = 0;
 
        if (!urb)
@@ -683,9 +681,6 @@ static void usb_rx_callback(struct urb *urb)
        if (!context)
                return;
 
-       buf = urb->transfer_buffer;
-       len = urb->actual_length;
-
        switch (urb->status) {
        case -ENOENT:           /* usbcore unlink successful! */
                return;
@@ -728,7 +723,6 @@ static int imon_probe(struct usb_interface *interface,
        int ir_ep_found = 0;
        int alloc_status = 0;
        int vfd_proto_6p = 0;
-       int code_length;
        struct imon_context *context = NULL;
        int i;
        u16 vendor, product;
@@ -749,8 +743,6 @@ static int imon_probe(struct usb_interface *interface,
        else
                context->display = 1;
 
-       code_length = BUF_CHUNK_SIZE * 8;
-
        usbdev     = usb_get_dev(interface_to_usbdev(interface));
        iface_desc = interface->cur_altsetting;
        num_endpts = iface_desc->desc.bNumEndpoints;
@@ -856,7 +848,7 @@ static int imon_probe(struct usb_interface *interface,
 
        strcpy(driver->name, MOD_NAME);
        driver->minor = -1;
-       driver->code_length = sizeof(int) * 8;
+       driver->code_length = BUF_CHUNK_SIZE * 8;
        driver->sample_rate = 0;
        driver->features = LIRC_CAN_REC_MODE2;
        driver->data = context;
index 4a3cca0..805df91 100644 (file)
@@ -838,7 +838,23 @@ static int hardware_init_port(void)
 
 static int init_port(void)
 {
-       int i, nlow, nhigh;
+       int i, nlow, nhigh, result;
+
+       result = request_irq(irq, irq_handler,
+                            IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0),
+                            LIRC_DRIVER_NAME, (void *)&hardware);
+
+       switch (result) {
+       case -EBUSY:
+               printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
+               return -EBUSY;
+       case -EINVAL:
+               printk(KERN_ERR LIRC_DRIVER_NAME
+                      ": Bad irq number or handler\n");
+               return -EINVAL;
+       default:
+               break;
+       };
 
        /* Reserve io region. */
        /*
@@ -893,34 +909,17 @@ static int init_port(void)
                printk(KERN_INFO LIRC_DRIVER_NAME  ": Manually using active "
                       "%s receiver\n", sense ? "low" : "high");
 
+       dprintk("Interrupt %d, port %04x obtained\n", irq, io);
        return 0;
 }
 
 static int set_use_inc(void *data)
 {
-       int result;
        unsigned long flags;
 
        /* initialize timestamp */
        do_gettimeofday(&lasttv);
 
-       result = request_irq(irq, irq_handler,
-                            IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0),
-                            LIRC_DRIVER_NAME, (void *)&hardware);
-
-       switch (result) {
-       case -EBUSY:
-               printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
-               return -EBUSY;
-       case -EINVAL:
-               printk(KERN_ERR LIRC_DRIVER_NAME
-                      ": Bad irq number or handler\n");
-               return -EINVAL;
-       default:
-               dprintk("Interrupt %d, port %04x obtained\n", irq, io);
-               break;
-       }
-
        spin_lock_irqsave(&hardware[type].lock, flags);
 
        /* Set DLAB 0. */
@@ -945,10 +944,6 @@ static void set_use_dec(void *data)
        soutp(UART_IER, sinp(UART_IER) &
              (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
        spin_unlock_irqrestore(&hardware[type].lock, flags);
-
-       free_irq(irq, (void *)&hardware);
-
-       dprintk("freed IRQ %d\n", irq);
 }
 
 static ssize_t lirc_write(struct file *file, const char *buf,
@@ -1256,6 +1251,9 @@ exit_serial_exit:
 static void __exit lirc_serial_exit_module(void)
 {
        lirc_serial_exit();
+
+       free_irq(irq, (void *)&hardware);
+
        if (iommap != 0)
                release_mem_region(iommap, 8 << ioshift);
        else
index a7b46f2..0d38645 100644 (file)
@@ -739,23 +739,16 @@ static void send_space(unsigned long len)
 static void send_pulse(unsigned long len)
 {
        long bytes_out = len / TIME_CONST;
-       long time_left;
 
-       time_left = (long)len - (long)bytes_out * (long)TIME_CONST;
-       if (bytes_out == 0) {
+       if (bytes_out == 0)
                bytes_out++;
-               time_left = 0;
-       }
+
        while (bytes_out--) {
                outb(PULSE, io + UART_TX);
                /* FIXME treba seriozne cakanie z char/serial.c */
                while (!(inb(io + UART_LSR) & UART_LSR_THRE))
                        ;
        }
-#if 0
-       if (time_left > 0)
-               safe_udelay(time_left);
-#endif
 }
 #endif
 
index dd6a57c..4e051f6 100644 (file)
@@ -475,14 +475,14 @@ static int lirc_thread(void *arg)
        dprintk("poll thread started\n");
 
        while (!kthread_should_stop()) {
+               set_current_state(TASK_INTERRUPTIBLE);
+
                /* if device not opened, we can sleep half a second */
                if (atomic_read(&ir->open_count) == 0) {
                        schedule_timeout(HZ/2);
                        continue;
                }
 
-               set_current_state(TASK_INTERRUPTIBLE);
-
                /*
                 * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
                 * We use this interval as the chip resets every time you poll
index 64c7ab4..0b5ec23 100644 (file)
@@ -1147,6 +1147,14 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
         * any drivers bound to them (a key side effect)
         */
        if (dev->actconfig) {
+               /*
+                * FIXME: In order to avoid self-deadlock involving the
+                * bandwidth_mutex, we have to mark all the interfaces
+                * before unregistering any of them.
+                */
+               for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
+                       dev->actconfig->interface[i]->unregistering = 1;
+
                for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
                        struct usb_interface    *interface;
 
@@ -1156,7 +1164,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                                continue;
                        dev_dbg(&dev->dev, "unregistering interface %s\n",
                                dev_name(&interface->dev));
-                       interface->unregistering = 1;
                        remove_intf_ep_devs(interface);
                        device_del(&interface->dev);
                }
@@ -1286,6 +1293,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
                        interface);
                return -EINVAL;
        }
+       if (iface->unregistering)
+               return -ENODEV;
 
        alt = usb_altnum_to_altsetting(iface, alternate);
        if (!alt) {
index 2cd9a60..4e48331 100644 (file)
@@ -46,7 +46,6 @@
 #include <asm/system.h>
 #include <asm/unaligned.h>
 #include <asm/dma.h>
-#include <asm/cacheflush.h>
 
 #include "fsl_usb2_udc.h"
 
@@ -118,6 +117,17 @@ static void (*_fsl_writel)(u32 v, unsigned __iomem *p);
 #define fsl_readl(p)           (*_fsl_readl)((p))
 #define fsl_writel(v, p)       (*_fsl_writel)((v), (p))
 
+static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata)
+{
+       if (pdata->big_endian_mmio) {
+               _fsl_readl = _fsl_readl_be;
+               _fsl_writel = _fsl_writel_be;
+       } else {
+               _fsl_readl = _fsl_readl_le;
+               _fsl_writel = _fsl_writel_le;
+       }
+}
+
 static inline u32 cpu_to_hc32(const u32 x)
 {
        return udc_controller->pdata->big_endian_desc
@@ -132,6 +142,8 @@ static inline u32 hc32_to_cpu(const u32 x)
                : le32_to_cpu((__force __le32)x);
 }
 #else /* !CONFIG_PPC32 */
+static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) {}
+
 #define fsl_readl(addr)                readl(addr)
 #define fsl_writel(val32, addr) writel(val32, addr)
 #define cpu_to_hc32(x)         cpu_to_le32(x)
@@ -1277,6 +1289,11 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
        req->req.complete = NULL;
        req->dtd_count = 0;
 
+       req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+                       req->req.buf, req->req.length,
+                       ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+       req->mapped = 1;
+
        if (fsl_req_to_dtd(req) == 0)
                fsl_queue_td(ep, req);
        else
@@ -1348,9 +1365,6 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
        /* Fill in the reqest structure */
        *((u16 *) req->req.buf) = cpu_to_le16(tmp);
 
-       /* flush cache for the req buffer */
-       flush_dcache_range((u32)req->req.buf, (u32)req->req.buf + 8);
-
        req->ep = ep;
        req->req.length = 2;
        req->req.status = -EINPROGRESS;
@@ -1358,6 +1372,11 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
        req->req.complete = NULL;
        req->dtd_count = 0;
 
+       req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+                               req->req.buf, req->req.length,
+                               ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+       req->mapped = 1;
+
        /* prime the data phase */
        if ((fsl_req_to_dtd(req) == 0))
                fsl_queue_td(ep, req);
@@ -2354,7 +2373,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc,
                        struct fsl_req, req);
        /* allocate a small amount of memory to get valid address */
        udc->status_req->req.buf = kmalloc(8, GFP_KERNEL);
-       udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf);
 
        udc->resume_state = USB_STATE_NOTATTACHED;
        udc->usb_state = USB_STATE_POWERED;
@@ -2470,13 +2488,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
        }
 
        /* Set accessors only after pdata->init() ! */
-       if (pdata->big_endian_mmio) {
-               _fsl_readl = _fsl_readl_be;
-               _fsl_writel = _fsl_writel_be;
-       } else {
-               _fsl_readl = _fsl_readl_le;
-               _fsl_writel = _fsl_writel_le;
-       }
+       fsl_set_accessors(pdata);
 
 #ifndef CONFIG_ARCH_MXC
        if (pdata->have_sysif_regs)
index 63039ed..2bc5dc6 100644 (file)
@@ -1864,6 +1864,7 @@ cleanup:
        kfree(psinfo);
        kfree(notes);
        kfree(fpu);
+       kfree(shdr4extnum);
 #ifdef ELF_CORE_COPY_XFPREGS
        kfree(xfpu);
 #endif
index 9542f07..4698a5c 100644 (file)
@@ -290,7 +290,6 @@ static int striped_read(struct inode *inode,
        struct ceph_inode_info *ci = ceph_inode(inode);
        u64 pos, this_len;
        int io_align, page_align;
-       int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */
        int left, pages_left;
        int read;
        struct page **page_pos;
@@ -326,12 +325,11 @@ more:
             ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
 
        if (ret > 0) {
-               int didpages =
-                       ((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT;
+               int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
 
                if (read < pos - off) {
                        dout(" zero gap %llu to %llu\n", off + read, pos);
-                       ceph_zero_page_vector_range(page_off + read,
+                       ceph_zero_page_vector_range(page_align + read,
                                                    pos - off - read, pages);
                }
                pos += ret;
@@ -356,7 +354,7 @@ more:
                                left = inode->i_size - pos;
 
                        dout("zero tail %d\n", left);
-                       ceph_zero_page_vector_range(page_off + read, left,
+                       ceph_zero_page_vector_range(page_align + read, left,
                                                    pages);
                        read += left;
                }
@@ -478,9 +476,6 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
        else
                pos = *offset;
 
-       io_align = pos & ~PAGE_MASK;
-       buf_align = (unsigned long)data & ~PAGE_MASK;
-
        ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
        if (ret < 0)
                return ret;
@@ -504,6 +499,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
         * boundary.  this isn't atomic, unfortunately.  :(
         */
 more:
+       io_align = pos & ~PAGE_MASK;
+       buf_align = (unsigned long)data & ~PAGE_MASK;
        len = left;
        if (file->f_flags & O_DIRECT) {
                /* write from beginning of first page, regardless of
@@ -593,6 +590,7 @@ out:
                pos += len;
                written += len;
                left -= len;
+               data += written;
                if (left)
                        goto more;
 
index 8166966..42e5363 100644 (file)
@@ -92,6 +92,7 @@ static void cifs_fscache_disable_inode_cookie(struct inode *inode)
 
        if (cifsi->fscache) {
                cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache);
+               fscache_uncache_all_inode_pages(cifsi->fscache, inode);
                fscache_relinquish_cookie(cifsi->fscache, 1);
                cifsi->fscache = NULL;
        }
index a2a5d19..2f343b4 100644 (file)
@@ -954,3 +954,47 @@ void fscache_mark_pages_cached(struct fscache_retrieval *op,
        pagevec_reinit(pagevec);
 }
 EXPORT_SYMBOL(fscache_mark_pages_cached);
+
+/*
+ * Uncache all the pages in an inode that are marked PG_fscache, assuming them
+ * to be associated with the given cookie.
+ */
+void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
+                                      struct inode *inode)
+{
+       struct address_space *mapping = inode->i_mapping;
+       struct pagevec pvec;
+       pgoff_t next;
+       int i;
+
+       _enter("%p,%p", cookie, inode);
+
+       if (!mapping || mapping->nrpages == 0) {
+               _leave(" [no pages]");
+               return;
+       }
+
+       pagevec_init(&pvec, 0);
+       next = 0;
+       while (next <= (loff_t)-1 &&
+              pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)
+              ) {
+               for (i = 0; i < pagevec_count(&pvec); i++) {
+                       struct page *page = pvec.pages[i];
+                       pgoff_t page_index = page->index;
+
+                       ASSERTCMP(page_index, >=, next);
+                       next = page_index + 1;
+
+                       if (PageFsCache(page)) {
+                               __fscache_wait_on_page_write(cookie, page);
+                               __fscache_uncache_page(cookie, page);
+                       }
+               }
+               pagevec_release(&pvec);
+               cond_resched();
+       }
+
+       _leave("");
+}
+EXPORT_SYMBOL(__fscache_uncache_all_inode_pages);
index b49b555..84a47b7 100644 (file)
@@ -500,7 +500,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
 out_put_hidden_dir:
        iput(sbi->hidden_dir);
 out_put_root:
-       iput(sbi->alloc_file);
+       iput(root);
 out_put_alloc_file:
        iput(sbi->alloc_file);
 out_close_cat_tree:
index 3031d81..4ac88ff 100644 (file)
@@ -36,6 +36,7 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
 {
        DECLARE_COMPLETION_ONSTACK(wait);
        struct bio *bio;
+       int ret = 0;
 
        bio = bio_alloc(GFP_NOIO, 1);
        bio->bi_sector = sector;
@@ -54,8 +55,10 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector,
        wait_for_completion(&wait);
 
        if (!bio_flagged(bio, BIO_UPTODATE))
-               return -EIO;
-       return 0;
+               ret = -EIO;
+
+       bio_put(bio);
+       return ret;
 }
 
 static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd)
index 0a4f50d..b286539 100644 (file)
@@ -160,10 +160,28 @@ EXPORT_SYMBOL_GPL(unlock_flocks);
 
 static struct kmem_cache *filelock_cache __read_mostly;
 
+static void locks_init_lock_always(struct file_lock *fl)
+{
+       fl->fl_next = NULL;
+       fl->fl_fasync = NULL;
+       fl->fl_owner = NULL;
+       fl->fl_pid = 0;
+       fl->fl_nspid = NULL;
+       fl->fl_file = NULL;
+       fl->fl_flags = 0;
+       fl->fl_type = 0;
+       fl->fl_start = fl->fl_end = 0;
+}
+
 /* Allocate an empty lock structure. */
 struct file_lock *locks_alloc_lock(void)
 {
-       return kmem_cache_alloc(filelock_cache, GFP_KERNEL);
+       struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL);
+
+       if (fl)
+               locks_init_lock_always(fl);
+
+       return fl;
 }
 EXPORT_SYMBOL_GPL(locks_alloc_lock);
 
@@ -200,17 +218,9 @@ void locks_init_lock(struct file_lock *fl)
        INIT_LIST_HEAD(&fl->fl_link);
        INIT_LIST_HEAD(&fl->fl_block);
        init_waitqueue_head(&fl->fl_wait);
-       fl->fl_next = NULL;
-       fl->fl_fasync = NULL;
-       fl->fl_owner = NULL;
-       fl->fl_pid = 0;
-       fl->fl_nspid = NULL;
-       fl->fl_file = NULL;
-       fl->fl_flags = 0;
-       fl->fl_type = 0;
-       fl->fl_start = fl->fl_end = 0;
        fl->fl_ops = NULL;
        fl->fl_lmops = NULL;
+       locks_init_lock_always(fl);
 }
 
 EXPORT_SYMBOL(locks_init_lock);
index ce153a6..419119c 100644 (file)
@@ -259,12 +259,10 @@ static void nfs_fscache_disable_inode_cookie(struct inode *inode)
                dfprintk(FSCACHE,
                         "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode));
 
-               /* Need to invalidate any mapped pages that were read in before
-                * turning off the cache.
+               /* Need to uncache any pages attached to this inode that
+                * fscache knows about before turning off the cache.
                 */
-               if (inode->i_mapping && inode->i_mapping->nrpages)
-                       invalidate_inode_pages2(inode->i_mapping);
-
+               fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode);
                nfs_fscache_zap_inode_cookie(inode);
        }
 }
index 09983a3..b1e88d5 100644 (file)
@@ -681,15 +681,15 @@ xfs_inode_item_unlock(
  * where the cluster buffer may be unpinned before the inode is inserted into
  * the AIL during transaction committed processing. If the buffer is unpinned
  * before the inode item has been committed and inserted, then it is possible
- * for the buffer to be written and IO completions before the inode is inserted
+ * for the buffer to be written and IO completes before the inode is inserted
  * into the AIL. In that case, we'd be inserting a clean, stale inode into the
  * AIL which will never get removed. It will, however, get reclaimed which
  * triggers an assert in xfs_inode_free() complaining about freein an inode
  * still in the AIL.
  *
- * To avoid this, return a lower LSN than the one passed in so that the
- * transaction committed code will not move the inode forward in the AIL but
- * will still unpin it properly.
+ * To avoid this, just unpin the inode directly and return a LSN of -1 so the
+ * transaction committed code knows that it does not need to do any further
+ * processing on the item.
  */
 STATIC xfs_lsn_t
 xfs_inode_item_committed(
@@ -699,8 +699,10 @@ xfs_inode_item_committed(
        struct xfs_inode_log_item *iip = INODE_ITEM(lip);
        struct xfs_inode        *ip = iip->ili_inode;
 
-       if (xfs_iflags_test(ip, XFS_ISTALE))
-               return lsn - 1;
+       if (xfs_iflags_test(ip, XFS_ISTALE)) {
+               xfs_inode_item_unpin(lip, 0);
+               return -1;
+       }
        return lsn;
 }
 
index 7c7bc2b..c83f63b 100644 (file)
@@ -1361,7 +1361,7 @@ xfs_trans_item_committed(
                lip->li_flags |= XFS_LI_ABORTED;
        item_lsn = IOP_COMMITTED(lip, commit_lsn);
 
-       /* If the committed routine returns -1, item has been freed. */
+       /* item_lsn of -1 means the item needs no further processing */
        if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
                return;
 
@@ -1474,7 +1474,7 @@ xfs_trans_committed_bulk(
                        lip->li_flags |= XFS_LI_ABORTED;
                item_lsn = IOP_COMMITTED(lip, commit_lsn);
 
-               /* item_lsn of -1 means the item was freed */
+               /* item_lsn of -1 means the item needs no further processing */
                if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
                        continue;
 
index 246f576..447c367 100644 (file)
 /* drbdsetup XY resize -d Z
  * you are free to reduce the device size to nothing, if you want to.
  * the upper limit with 64bit kernel, enough ram and flexible meta data
- * is 16 TB, currently. */
+ * is 1 PiB, currently. */
 /* DRBD_MAX_SECTORS */
 #define DRBD_DISK_SIZE_SECT_MIN  0
-#define DRBD_DISK_SIZE_SECT_MAX  (16 * (2LLU << 30))
+#define DRBD_DISK_SIZE_SECT_MAX  (1 * (2LLU << 40))
 #define DRBD_DISK_SIZE_SECT_DEF  0 /* = disabled = no user size... */
 
 #define DRBD_ON_IO_ERROR_DEF EP_PASS_ON
index 7c4d72f..9ec20de 100644 (file)
@@ -204,6 +204,8 @@ extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
 extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
 extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *,
                                         gfp_t);
+extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *,
+                                             struct inode *);
 
 /**
  * fscache_register_netfs - Register a filesystem as desiring caching services
@@ -643,4 +645,23 @@ bool fscache_maybe_release_page(struct fscache_cookie *cookie,
        return false;
 }
 
+/**
+ * fscache_uncache_all_inode_pages - Uncache all an inode's pages
+ * @cookie: The cookie representing the inode's cache object.
+ * @inode: The inode to uncache pages from.
+ *
+ * Uncache all the pages in an inode that are marked PG_fscache, assuming them
+ * to be associated with the given cookie.
+ *
+ * This function may sleep.  It will wait for pages that are being written out
+ * and will wait whilst the PG_fscache mark is removed by the cache.
+ */
+static inline
+void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
+                                    struct inode *inode)
+{
+       if (fscache_cookie_valid(cookie))
+               __fscache_uncache_all_inode_pages(cookie, inode);
+}
+
 #endif /* _LINUX_FSCACHE_H */
index a837b20..496770a 100644 (file)
@@ -808,7 +808,7 @@ enum cpu_idle_type {
  * when BITS_PER_LONG <= 32 are pretty high and the returns do not justify the
  * increased costs.
  */
-#if BITS_PER_LONG > 32
+#if 0 /* BITS_PER_LONG > 32 -- currently broken: it increases power usage under light load  */
 # define SCHED_LOAD_RESOLUTION 10
 # define scale_load(w)         ((w) << SCHED_LOAD_RESOLUTION)
 # define scale_load_down(w)    ((w) >> SCHED_LOAD_RESOLUTION)
index 630e702..168dd0b 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef _LINUX_LIRC_DEV_H
 #define _LINUX_LIRC_DEV_H
 
-#define MAX_IRCTL_DEVICES 4
+#define MAX_IRCTL_DEVICES 8
 #define BUFLEN            16
 
 #define mod(n, div) ((n) % (div))
index 2d7e7ca..aac2c0e 100644 (file)
@@ -2,10 +2,10 @@
  * Driver 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
index 0589f55..396e8fc 100644 (file)
@@ -2688,7 +2688,7 @@ void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
  * @dev: network device
  * @addr: The source MAC address of the frame
  * @key_type: The key type that the received frame used
- * @key_id: Key identifier (0..3)
+ * @key_id: Key identifier (0..3). Can be -1 if missing.
  * @tsc: The TSC value of the frame that generated the MIC failure (6 octets)
  * @gfp: allocation flags
  *
index 7d15d23..e12ddfb 100644 (file)
@@ -77,6 +77,7 @@ struct dst_entry {
 #define DST_NOPOLICY           0x0004
 #define DST_NOHASH             0x0008
 #define DST_NOCACHE            0x0010
+#define DST_NOCOUNT            0x0020
        union {
                struct dst_entry        *next;
                struct rtable __rcu     *rt_next;
index fa27e75..a8ce450 100644 (file)
@@ -375,15 +375,19 @@ int jump_label_text_reserved(void *start, void *end)
 
 static void jump_label_update(struct jump_label_key *key, int enable)
 {
-       struct jump_entry *entry = key->entries;
-
-       /* if there are no users, entry can be NULL */
-       if (entry)
-               __jump_label_update(key, entry, __stop___jump_table, enable);
+       struct jump_entry *entry = key->entries, *stop = __stop___jump_table;
 
 #ifdef CONFIG_MODULES
+       struct module *mod = __module_address((jump_label_t)key);
+
        __jump_label_mod_update(key, enable);
+
+       if (mod)
+               stop = mod->jump_entries + mod->num_jump_entries;
 #endif
+       /* if there are no users, entry can be NULL */
+       if (entry)
+               __jump_label_update(key, entry, stop, enable);
 }
 
 #endif
index ace5588..06efa54 100644 (file)
@@ -1211,7 +1211,11 @@ static void free_unnecessary_pages(void)
                to_free_highmem = alloc_highmem - save;
        } else {
                to_free_highmem = 0;
-               to_free_normal -= save - alloc_highmem;
+               save -= alloc_highmem;
+               if (to_free_normal > save)
+                       to_free_normal -= save;
+               else
+                       to_free_normal = 0;
        }
 
        memory_bm_position_reset(&copy_bm);
index 798e2fa..3ff4017 100644 (file)
@@ -38,6 +38,14 @@ struct resource iomem_resource = {
 };
 EXPORT_SYMBOL(iomem_resource);
 
+/* constraints to be met while allocating resources */
+struct resource_constraint {
+       resource_size_t min, max, align;
+       resource_size_t (*alignf)(void *, const struct resource *,
+                       resource_size_t, resource_size_t);
+       void *alignf_data;
+};
+
 static DEFINE_RWLOCK(resource_lock);
 
 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
@@ -384,16 +392,13 @@ static bool resource_contains(struct resource *res1, struct resource *res2)
 }
 
 /*
- * Find empty slot in the resource tree given range and alignment.
+ * Find empty slot in the resource tree with the given range and
+ * alignment constraints
  */
-static int find_resource(struct resource *root, struct resource *new,
-                        resource_size_t size, resource_size_t min,
-                        resource_size_t max, resource_size_t align,
-                        resource_size_t (*alignf)(void *,
-                                                  const struct resource *,
-                                                  resource_size_t,
-                                                  resource_size_t),
-                        void *alignf_data)
+static int __find_resource(struct resource *root, struct resource *old,
+                        struct resource *new,
+                        resource_size_t  size,
+                        struct resource_constraint *constraint)
 {
        struct resource *this = root->child;
        struct resource tmp = *new, avail, alloc;
@@ -404,25 +409,26 @@ static int find_resource(struct resource *root, struct resource *new,
         * Skip past an allocated resource that starts at 0, since the assignment