Merge branch 'akpm' (Andrew's patch-bomb)
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Apr 2012 21:15:21 +0000 (14:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Apr 2012 21:15:21 +0000 (14:15 -0700)
Merge fixes from Andrew Morton.

* emailed from Andrew Morton <akpm@linux-foundation.org>: (14 patches)
  panic: fix stack dump print on direct call to panic()
  drivers/rtc/rtc-pl031.c: enable clock on all ST variants
  Revert "mm: vmscan: fix misused nr_reclaimed in shrink_mem_cgroup_zone()"
  hugetlb: fix race condition in hugetlb_fault()
  drivers/rtc/rtc-twl.c: use static register while reading time
  drivers/rtc/rtc-s3c.c: add placeholder for driver private data
  drivers/rtc/rtc-s3c.c: fix compilation error
  MAINTAINERS: add PCDP console maintainer
  memcg: do not open code accesses to res_counter members
  drivers/rtc/rtc-efi.c: fix section mismatch warning
  drivers/rtc/rtc-r9701.c: reset registers if invalid values are detected
  drivers/char/random.c: fix boot id uniqueness race
  memcg: fix broken boolen expression
  memcg: fix up documentation on global LRU

93 files changed:
Documentation/filesystems/vfs.txt
MAINTAINERS
arch/c6x/include/asm/irq.h
arch/c6x/kernel/irq.c
arch/powerpc/include/asm/irq.h
arch/powerpc/kernel/irq.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/beat_interrupt.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/ps3/interrupt.c
drivers/bcma/Kconfig
drivers/bcma/driver_pci_host.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_ldisc.c
drivers/gpu/drm/exynos/exynos_drm_buf.c
drivers/gpu/drm/exynos/exynos_drm_core.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/exynos/exynos_drm_hdmi.c
drivers/gpu/drm/exynos/exynos_drm_hdmi.h
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/radeon_clocks.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/savage/savage_state.c
drivers/input/misc/da9052_onkey.c
drivers/input/mouse/elantech.c
drivers/input/mouse/gpio_mouse.c
drivers/input/mouse/sentelic.c
drivers/input/mouse/trackpoint.c
drivers/input/touchscreen/tps6507x-ts.c
drivers/md/bitmap.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/mtd/mtdchar.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/rtl8192de/sw.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/rtlwifi/wifi.h
fs/libfs.c
include/drm/exynos_drm.h
include/linux/irq.h
include/linux/irqdomain.h
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/skbuff.h
include/linux/types.h
include/linux/vgaarb.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt.h
include/net/mac80211.h
kernel/irq/Kconfig
kernel/irq/irqdomain.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bridge/br_multicast.c
net/bridge/br_private.h
net/core/skbuff.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv6/netfilter/ip6_tables.c
net/mac80211/mlme.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto_tcp.c
net/nfc/llcp/commands.c
net/wireless/nl80211.c
net/wireless/wext-core.c

index e916e3d36488d982b4cc1a8580ea5f0529af79d2..0d0492028082c0ecda1a0931cc5100765624a80a 100644 (file)
@@ -114,7 +114,7 @@ members are defined:
 struct file_system_type {
        const char *name;
        int fs_flags;
-        struct dentry (*mount) (struct file_system_type *, int,
+        struct dentry *(*mount) (struct file_system_type *, int,
                        const char *, void *);
         void (*kill_sb) (struct super_block *);
         struct module *owner;
index a068fe457f7a94f0a5bea308611d6f0b6e2b251b..32671e00800dd6d9c94eebed48e8ec8b870fcc7d 100644 (file)
@@ -1521,8 +1521,8 @@ M:        Gustavo Padovan <gustavo@padovan.org>
 M:     Johan Hedberg <johan.hedberg@gmail.com>
 L:     linux-bluetooth@vger.kernel.org
 W:     http://www.bluez.org/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
 S:     Maintained
 F:     drivers/bluetooth/
 
@@ -1532,8 +1532,8 @@ M:        Gustavo Padovan <gustavo@padovan.org>
 M:     Johan Hedberg <johan.hedberg@gmail.com>
 L:     linux-bluetooth@vger.kernel.org
 W:     http://www.bluez.org/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
 S:     Maintained
 F:     net/bluetooth/
 F:     include/net/bluetooth/
@@ -4533,8 +4533,7 @@ S:        Supported
 F:     drivers/net/ethernet/myricom/myri10ge/
 
 NATSEMI ETHERNET DRIVER (DP8381x)
-M:     Tim Hockin <thockin@hockin.org>
-S:     Maintained
+S:     Orphan
 F:     drivers/net/ethernet/natsemi/natsemi.c
 
 NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
index f13b78d5e1ca2c8f170357dd39c35d124f445daf..ab4577f93d96c97f347936a33a75dce2825df0c4 100644 (file)
 /* This number is used when no interrupt has been assigned */
 #define NO_IRQ         0
 
-struct irq_data;
-extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
-extern irq_hw_number_t virq_to_hw(unsigned int virq);
-
 extern void __init init_pic_c64xplus(void);
 
 extern void init_IRQ(void);
index 65b8ddf54b446ca904780dbc02a2e181fde037b1..c90fb5e82ad7b829fb9be3a9d562118374eff901 100644 (file)
@@ -130,16 +130,3 @@ int arch_show_interrupts(struct seq_file *p, int prec)
        seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
        return 0;
 }
-
-irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
-{
-       return d->hwirq;
-}
-EXPORT_SYMBOL_GPL(irqd_to_hwirq);
-
-irq_hw_number_t virq_to_hw(unsigned int virq)
-{
-       struct irq_data *irq_data = irq_get_irq_data(virq);
-       return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
-}
-EXPORT_SYMBOL_GPL(virq_to_hw);
index cf417e51073627ff6184f15ddd3a78f7948419c7..e648af92ced18b20384102912fbaeafc903ddfb0 100644 (file)
@@ -33,8 +33,6 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Same thing, used by the generic IRQ code */
 #define NR_IRQS_LEGACY         NUM_ISA_INTERRUPTS
 
-struct irq_data;
-extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
 
 /**
index 243dbabfe74dff0ebbe55fab216a335574c1dc12..5ec1b2354ca62301b83019db2f342bd92c085b80 100644 (file)
@@ -560,12 +560,6 @@ void do_softirq(void)
        local_irq_restore(flags);
 }
 
-irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
-{
-       return d->hwirq;
-}
-EXPORT_SYMBOL_GPL(irqd_to_hwirq);
-
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
        struct irq_data *irq_data = irq_get_irq_data(virq);
index db360fc4cf0e616a9f463c37f197ee04ba4d657d..d09f3e8e68670585230e52d33c28109d9ce6cf8e 100644 (file)
@@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device)
        }
        memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
-       msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
+       msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic);
        if (!msic->irq_domain) {
                printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
                       dn->full_name);
index e5c3a2c6090d186b5ddeb5941514bda73d165065..f9a48af335cb8d17b52cb1ed34503175d0772fef 100644 (file)
@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
        ppc_md.get_irq = beatic_get_irq;
 
        /* Allocate an irq host */
-       beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
+       beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL);
        BUG_ON(beatic_host == NULL);
        irq_set_default_host(beatic_host);
 }
index a81e5a88fbdf1c49c70cba6ef2699b86ed95d7b5..b4ddaa3fbb298eccc37044f61222d38a688c9f8c 100644 (file)
@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
        int rc = -ENOMEM;
 
-       psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
+       psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL);
 
        if (psurge_host)
                psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
index 2a4ff86cc21f72c5c0af0082e4c12c64de5db6cd..5f3b23220b8ee395e0d9e05821a43b98fd8592f1 100644 (file)
@@ -753,9 +753,8 @@ void __init ps3_init_IRQ(void)
        unsigned cpu;
        struct irq_domain *host;
 
-       host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
+       host = irq_domain_add_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL);
        irq_set_default_host(host);
-       irq_set_virq_count(PS3_PLUG_MAX + 1);
 
        for_each_possible_cpu(cpu) {
                struct ps3_private *pd = &per_cpu(ps3_private, cpu);
index c1172dafdffac1c7688155dc20a658628c6934ca..fb7c80fb721e2466d405deedc367967179ea1d80 100644 (file)
@@ -29,7 +29,7 @@ config BCMA_HOST_PCI
 
 config BCMA_DRIVER_PCI_HOSTMODE
        bool "Driver for PCI core working in hostmode"
-       depends on BCMA && MIPS
+       depends on BCMA && MIPS && BCMA_HOST_PCI
        help
          PCI core hostmode operation (external PCI bus).
 
index 4e20bcfa7ec5d3e62bdf34004601c2edca813ddc..d2097a11c3c7ae259f7e18dd4b5ff934c5ee85a9 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/pci.h>
 #include <linux/export.h>
 #include <linux/bcma/bcma.h>
 #include <asm/paccess.h>
index 48442476ec005415ec0d51c79c48e305ed31fb69..ae9edca7b56dc474a140c8f0eb579f556dc8e308 100644 (file)
@@ -72,7 +72,9 @@ static struct usb_device_id ath3k_table[] = {
 
        /* Atheros AR3012 with sflash firmware*/
        { USB_DEVICE(0x0CF3, 0x3004) },
+       { USB_DEVICE(0x0CF3, 0x311D) },
        { USB_DEVICE(0x13d3, 0x3375) },
+       { USB_DEVICE(0x04CA, 0x3005) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -89,7 +91,9 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 
        /* Atheros AR3012 with sflash firmware*/
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 
        { }     /* Terminating entry */
 };
index 480cad9200481fb0ad2eb9a91c5b9b55d2dea5c5..3311b812a0c68a37c9728c7bef3af2c050af587b 100644 (file)
@@ -61,7 +61,7 @@ static struct usb_device_id btusb_table[] = {
        { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
        /* Broadcom SoftSailing reporting vendor specific */
-       { USB_DEVICE(0x05ac, 0x21e1) },
+       { USB_DEVICE(0x0a5c, 0x21e1) },
 
        /* Apple MacBookPro 7,1 */
        { USB_DEVICE(0x05ac, 0x8213) },
@@ -103,6 +103,7 @@ static struct usb_device_id btusb_table[] = {
        /* Broadcom BCM20702A0 */
        { USB_DEVICE(0x0a5c, 0x21e3) },
        { USB_DEVICE(0x0a5c, 0x21e6) },
+       { USB_DEVICE(0x0a5c, 0x21e8) },
        { USB_DEVICE(0x0a5c, 0x21f3) },
        { USB_DEVICE(0x413c, 0x8197) },
 
@@ -129,7 +130,9 @@ static struct usb_device_id blacklist_table[] = {
 
        /* Atheros 3012 with sflash firmware */
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
index fd5adb408f447a4a08b9dbece913e111d3fe9906..98a8c05d4f23a038dfa020cd98930c9d52283844 100644 (file)
@@ -299,11 +299,11 @@ static void hci_uart_tty_close(struct tty_struct *tty)
                        hci_uart_close(hdev);
 
                if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-                       hu->proto->close(hu);
                        if (hdev) {
                                hci_unregister_dev(hdev);
                                hci_free_dev(hdev);
                        }
+                       hu->proto->close(hu);
                }
 
                kfree(hu);
index 4a3a5f72ed4a42938dd38b998752c63baf953304..de8d2090bce32c769c3c04b0d8105933b648340a 100644 (file)
 static int lowlevel_buffer_allocate(struct drm_device *dev,
                unsigned int flags, struct exynos_drm_gem_buf *buf)
 {
-       dma_addr_t start_addr, end_addr;
+       dma_addr_t start_addr;
        unsigned int npages, page_size, i = 0;
        struct scatterlist *sgl;
        int ret = 0;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (flags & EXYNOS_BO_NONCONTIG) {
+       if (IS_NONCONTIG_BUFFER(flags)) {
                DRM_DEBUG_KMS("not support allocation type.\n");
                return -EINVAL;
        }
@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
        }
 
        if (buf->size >= SZ_1M) {
-               npages = (buf->size >> SECTION_SHIFT) + 1;
+               npages = buf->size >> SECTION_SHIFT;
                page_size = SECTION_SIZE;
        } else if (buf->size >= SZ_64K) {
-               npages = (buf->size >> 16) + 1;
+               npages = buf->size >> 16;
                page_size = SZ_64K;
        } else {
-               npages = (buf->size >> PAGE_SHIFT) + 1;
+               npages = buf->size >> PAGE_SHIFT;
                page_size = PAGE_SIZE;
        }
 
@@ -76,26 +76,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
                return -ENOMEM;
        }
 
-               buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
-                               &buf->dma_addr, GFP_KERNEL);
-               if (!buf->kvaddr) {
-                       DRM_ERROR("failed to allocate buffer.\n");
-                       ret = -ENOMEM;
-                       goto err1;
-               }
-
-               start_addr = buf->dma_addr;
-               end_addr = buf->dma_addr + buf->size;
-
-               buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
-               if (!buf->pages) {
-                       DRM_ERROR("failed to allocate pages.\n");
-                       ret = -ENOMEM;
-                       goto err2;
-               }
-
-       start_addr = buf->dma_addr;
-       end_addr = buf->dma_addr + buf->size;
+       buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
+                       &buf->dma_addr, GFP_KERNEL);
+       if (!buf->kvaddr) {
+               DRM_ERROR("failed to allocate buffer.\n");
+               ret = -ENOMEM;
+               goto err1;
+       }
 
        buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
        if (!buf->pages) {
@@ -105,23 +92,17 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
        }
 
        sgl = buf->sgt->sgl;
+       start_addr = buf->dma_addr;
 
        while (i < npages) {
                buf->pages[i] = phys_to_page(start_addr);
                sg_set_page(sgl, buf->pages[i], page_size, 0);
                sg_dma_address(sgl) = start_addr;
                start_addr += page_size;
-               if (end_addr - start_addr < page_size)
-                       break;
                sgl = sg_next(sgl);
                i++;
        }
 
-       buf->pages[i] = phys_to_page(start_addr);
-
-       sgl = sg_next(sgl);
-       sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
-
        DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
                        (unsigned long)buf->kvaddr,
                        (unsigned long)buf->dma_addr,
@@ -150,7 +131,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
         * non-continuous memory would be released by exynos
         * gem framework.
         */
-       if (flags & EXYNOS_BO_NONCONTIG) {
+       if (IS_NONCONTIG_BUFFER(flags)) {
                DRM_DEBUG_KMS("not support allocation type.\n");
                return;
        }
index 411832e8e17aa9fcd9eed13fc614be878f781403..eaf630dc5dba951e78f8a68c2d0bcc1b25ae40b3 100644 (file)
@@ -54,16 +54,18 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
                 *
                 * P.S. note that this driver is considered for modularization.
                 */
-               ret = subdrv->probe(dev, subdrv->manager.dev);
+               ret = subdrv->probe(dev, subdrv->dev);
                if (ret)
                        return ret;
        }
 
-       if (subdrv->is_local)
+       if (!subdrv->manager)
                return 0;
 
+       subdrv->manager->dev = subdrv->dev;
+
        /* create and initialize a encoder for this sub driver. */
-       encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
+       encoder = exynos_drm_encoder_create(dev, subdrv->manager,
                        (1 << MAX_CRTC) - 1);
        if (!encoder) {
                DRM_ERROR("failed to create encoder\n");
@@ -186,7 +188,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
 
        list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
                if (subdrv->open) {
-                       ret = subdrv->open(dev, subdrv->manager.dev, file);
+                       ret = subdrv->open(dev, subdrv->dev, file);
                        if (ret)
                                goto err;
                }
@@ -197,7 +199,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
 err:
        list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
                if (subdrv->close)
-                       subdrv->close(dev, subdrv->manager.dev, file);
+                       subdrv->close(dev, subdrv->dev, file);
        }
        return ret;
 }
@@ -209,7 +211,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
 
        list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
                if (subdrv->close)
-                       subdrv->close(dev, subdrv->manager.dev, file);
+                       subdrv->close(dev, subdrv->dev, file);
        }
 }
 EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
index fbd0a232c93dea173fc4582ebf9aa98c3c620f90..1d814175cd491d39d0411b31fa330c498f02c8c3 100644 (file)
@@ -225,24 +225,25 @@ struct exynos_drm_private {
  * Exynos drm sub driver structure.
  *
  * @list: sub driver has its own list object to register to exynos drm driver.
+ * @dev: pointer to device object for subdrv device driver.
  * @drm_dev: pointer to drm_device and this pointer would be set
  *     when sub driver calls exynos_drm_subdrv_register().
- * @is_local: appear encoder and connector disrelated device.
+ * @manager: subdrv has its own manager to control a hardware appropriately
+ *     and we can access a hardware drawing on this manager.
  * @probe: this callback would be called by exynos drm driver after
  *     subdrv is registered to it.
  * @remove: this callback is used to release resources created
  *     by probe callback.
  * @open: this would be called with drm device file open.
  * @close: this would be called with drm device file close.
- * @manager: subdrv has its own manager to control a hardware appropriately
- *     and we can access a hardware drawing on this manager.
  * @encoder: encoder object owned by this sub driver.
  * @connector: connector object owned by this sub driver.
  */
 struct exynos_drm_subdrv {
        struct list_head list;
+       struct device *dev;
        struct drm_device *drm_dev;
-       bool is_local;
+       struct exynos_drm_manager *manager;
 
        int (*probe)(struct drm_device *drm_dev, struct device *dev);
        void (*remove)(struct drm_device *dev);
@@ -251,7 +252,6 @@ struct exynos_drm_subdrv {
        void (*close)(struct drm_device *drm_dev, struct device *dev,
                        struct drm_file *file);
 
-       struct exynos_drm_manager manager;
        struct drm_encoder *encoder;
        struct drm_connector *connector;
 };
index ecb6db2297008f420ebb7b05e9e19b333bd37286..29fdbfeb43cb79645d034da2d7f8a7aba27dbe5b 100644 (file)
@@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode)
 static void fimd_apply(struct device *subdrv_dev)
 {
        struct fimd_context *ctx = get_fimd_context(subdrv_dev);
-       struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+       struct exynos_drm_manager *mgr = ctx->subdrv.manager;
        struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
        struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
        struct fimd_win_data *win_data;
@@ -577,6 +577,13 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = {
        .disable = fimd_win_disable,
 };
 
+static struct exynos_drm_manager fimd_manager = {
+       .pipe           = -1,
+       .ops            = &fimd_manager_ops,
+       .overlay_ops    = &fimd_overlay_ops,
+       .display_ops    = &fimd_display_ops,
+};
+
 static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
 {
        struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -628,7 +635,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
        struct fimd_context *ctx = (struct fimd_context *)dev_id;
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
        struct drm_device *drm_dev = subdrv->drm_dev;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
        u32 val;
 
        val = readl(ctx->regs + VIDINTCON1);
@@ -744,7 +751,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win)
 static int fimd_power_on(struct fimd_context *ctx, bool enable)
 {
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct device *dev = subdrv->manager.dev;
+       struct device *dev = subdrv->dev;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -867,13 +874,10 @@ static int __devinit fimd_probe(struct platform_device *pdev)
 
        subdrv = &ctx->subdrv;
 
+       subdrv->dev = dev;
+       subdrv->manager = &fimd_manager;
        subdrv->probe = fimd_subdrv_probe;
        subdrv->remove = fimd_subdrv_remove;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &fimd_manager_ops;
-       subdrv->manager.overlay_ops = &fimd_overlay_ops;
-       subdrv->manager.display_ops = &fimd_display_ops;
-       subdrv->manager.dev = dev;
 
        mutex_init(&ctx->lock);
 
index fa1aa94a3d8e3066f5abf21fdd02331b1d9b5219..26d51979116b456bb269cff95bc003d6a55394b1 100644 (file)
@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)
        return out_msg;
 }
 
-static unsigned int mask_gem_flags(unsigned int flags)
+static int check_gem_flags(unsigned int flags)
 {
-       return flags &= EXYNOS_BO_NONCONTIG;
+       if (flags & ~(EXYNOS_BO_MASK)) {
+               DRM_ERROR("invalid flags.\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
+{
+       if (!IS_NONCONTIG_BUFFER(flags)) {
+               if (size >= SZ_1M)
+                       return roundup(size, SECTION_SIZE);
+               else if (size >= SZ_64K)
+                       return roundup(size, SZ_64K);
+               else
+                       goto out;
+       }
+out:
+       return roundup(size, PAGE_SIZE);
 }
 
 static struct page **exynos_gem_get_pages(struct drm_gem_object *obj,
@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
        struct exynos_drm_gem_buf *buf;
        int ret;
 
-       size = roundup(size, PAGE_SIZE);
-       DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
+       if (!size) {
+               DRM_ERROR("invalid size.\n");
+               return ERR_PTR(-EINVAL);
+       }
 
-       flags = mask_gem_flags(flags);
+       size = roundup_gem_size(size, flags);
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       ret = check_gem_flags(flags);
+       if (ret)
+               return ERR_PTR(ret);
 
        buf = exynos_drm_init_buf(dev, size);
        if (!buf)
@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
        exynos_gem_obj = exynos_drm_gem_init(dev, size);
        if (!exynos_gem_obj) {
                ret = -ENOMEM;
-               goto err;
+               goto err_fini_buf;
        }
 
        exynos_gem_obj->buffer = buf;
@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
                ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
                if (ret < 0) {
                        drm_gem_object_release(&exynos_gem_obj->base);
-                       goto err;
+                       goto err_fini_buf;
                }
        } else {
                ret = exynos_drm_alloc_buf(dev, buf, flags);
                if (ret < 0) {
                        drm_gem_object_release(&exynos_gem_obj->base);
-                       goto err;
+                       goto err_fini_buf;
                }
        }
 
        return exynos_gem_obj;
-err:
+
+err_fini_buf:
        exynos_drm_fini_buf(dev, buf);
        return ERR_PTR(ret);
 }
index e40fbad8b70552abf83d2cf86ccd2cd4e10a5630..4ed842039505d5b6311b7252d5bdc514ec9df721 100644 (file)
@@ -29,6 +29,8 @@
 #define to_exynos_gem_obj(x)   container_of(x,\
                        struct exynos_drm_gem_obj, base)
 
+#define IS_NONCONTIG_BUFFER(f)         (f & EXYNOS_BO_NONCONTIG)
+
 /*
  * exynos drm gem buffer structure.
  *
index 14eb26b0ba1cb1fc70fb533be2adb38fd935ac71..3424463676e0997d4f653b11a400c7cf1f8aefd9 100644 (file)
@@ -30,9 +30,8 @@
                                        struct drm_hdmi_context, subdrv);
 
 /* these callback points shoud be set by specific drivers. */
-static struct exynos_hdmi_display_ops *hdmi_display_ops;
-static struct exynos_hdmi_manager_ops *hdmi_manager_ops;
-static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops;
+static struct exynos_hdmi_ops *hdmi_ops;
+static struct exynos_mixer_ops *mixer_ops;
 
 struct drm_hdmi_context {
        struct exynos_drm_subdrv        subdrv;
@@ -40,31 +39,20 @@ struct drm_hdmi_context {
        struct exynos_drm_hdmi_context  *mixer_ctx;
 };
 
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
-                                       *display_ops)
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (display_ops)
-               hdmi_display_ops = display_ops;
+       if (ops)
+               hdmi_ops = ops;
 }
 
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
-                                       *manager_ops)
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops)
 {
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (manager_ops)
-               hdmi_manager_ops = manager_ops;
-}
-
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
-                                       *overlay_ops)
-{
-       DRM_DEBUG_KMS("%s\n", __FILE__);
-
-       if (overlay_ops)
-               hdmi_overlay_ops = overlay_ops;
+       if (ops)
+               mixer_ops = ops;
 }
 
 static bool drm_hdmi_is_connected(struct device *dev)
@@ -73,8 +61,8 @@ static bool drm_hdmi_is_connected(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->is_connected)
-               return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx);
+       if (hdmi_ops && hdmi_ops->is_connected)
+               return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx);
 
        return false;
 }
@@ -86,9 +74,9 @@ static int drm_hdmi_get_edid(struct device *dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->get_edid)
-               return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx,
-                               connector, edid, len);
+       if (hdmi_ops && hdmi_ops->get_edid)
+               return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid,
+                                         len);
 
        return 0;
 }
@@ -99,9 +87,8 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->check_timing)
-               return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx,
-                               timing);
+       if (hdmi_ops && hdmi_ops->check_timing)
+               return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing);
 
        return 0;
 }
@@ -112,8 +99,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_display_ops && hdmi_display_ops->power_on)
-               return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode);
+       if (hdmi_ops && hdmi_ops->power_on)
+               return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode);
 
        return 0;
 }
@@ -130,13 +117,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev)
 {
        struct drm_hdmi_context *ctx = to_context(subdrv_dev);
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank)
-               return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx,
-                                                       manager->pipe);
+       if (mixer_ops && mixer_ops->enable_vblank)
+               return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx,
+                                               manager->pipe);
 
        return 0;
 }
@@ -147,8 +134,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank)
-               return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx);
+       if (mixer_ops && mixer_ops->disable_vblank)
+               return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx);
 }
 
 static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
@@ -160,9 +147,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup)
-               hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector,
-                                               mode, adjusted_mode);
+       if (hdmi_ops && hdmi_ops->mode_fixup)
+               hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
+                                    adjusted_mode);
 }
 
 static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
@@ -171,8 +158,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->mode_set)
-               hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
+       if (hdmi_ops && hdmi_ops->mode_set)
+               hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
 }
 
 static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
@@ -182,9 +169,8 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol)
-               hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width,
-                                                       height);
+       if (hdmi_ops && hdmi_ops->get_max_resol)
+               hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height);
 }
 
 static void drm_hdmi_commit(struct device *subdrv_dev)
@@ -193,8 +179,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_manager_ops && hdmi_manager_ops->commit)
-               hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx);
+       if (hdmi_ops && hdmi_ops->commit)
+               hdmi_ops->commit(ctx->hdmi_ctx->ctx);
 }
 
 static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
@@ -209,8 +195,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode)
        case DRM_MODE_DPMS_STANDBY:
        case DRM_MODE_DPMS_SUSPEND:
        case DRM_MODE_DPMS_OFF:
-               if (hdmi_manager_ops && hdmi_manager_ops->disable)
-                       hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx);
+               if (hdmi_ops && hdmi_ops->disable)
+                       hdmi_ops->disable(ctx->hdmi_ctx->ctx);
                break;
        default:
                DRM_DEBUG_KMS("unkown dps mode: %d\n", mode);
@@ -235,8 +221,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set)
-               hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
+       if (mixer_ops && mixer_ops->win_mode_set)
+               mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay);
 }
 
 static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
@@ -245,8 +231,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit)
-               hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
+       if (mixer_ops && mixer_ops->win_commit)
+               mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos);
 }
 
 static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
@@ -255,8 +241,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos)
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable)
-               hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
+       if (mixer_ops && mixer_ops->win_disable)
+               mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos);
 }
 
 static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
@@ -265,6 +251,12 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
        .disable = drm_mixer_disable,
 };
 
+static struct exynos_drm_manager hdmi_manager = {
+       .pipe           = -1,
+       .ops            = &drm_hdmi_manager_ops,
+       .overlay_ops    = &drm_hdmi_overlay_ops,
+       .display_ops    = &drm_hdmi_display_ops,
+};
 
 static int hdmi_subdrv_probe(struct drm_device *drm_dev,
                struct device *dev)
@@ -332,12 +324,9 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
 
        subdrv = &ctx->subdrv;
 
+       subdrv->dev = dev;
+       subdrv->manager = &hdmi_manager;
        subdrv->probe = hdmi_subdrv_probe;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &drm_hdmi_manager_ops;
-       subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops;
-       subdrv->manager.display_ops = &drm_hdmi_display_ops;
-       subdrv->manager.dev = dev;
 
        platform_set_drvdata(pdev, subdrv);
 
index 44497cfb6c74174ebb6faab6f5f0729ad712c43c..f3ae192c8dcf6e21b5977e5e210ceaf547f84999 100644 (file)
@@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context {
        void                    *ctx;
 };
 
-struct exynos_hdmi_display_ops {
+struct exynos_hdmi_ops {
+       /* display */
        bool (*is_connected)(void *ctx);
        int (*get_edid)(void *ctx, struct drm_connector *connector,
                        u8 *edid, int len);
        int (*check_timing)(void *ctx, void *timing);
        int (*power_on)(void *ctx, int mode);
-};
 
-struct exynos_hdmi_manager_ops {
+       /* manager */
        void (*mode_fixup)(void *ctx, struct drm_connector *connector,
                                struct drm_display_mode *mode,
                                struct drm_display_mode *adjusted_mode);
@@ -57,22 +57,17 @@ struct exynos_hdmi_manager_ops {
        void (*disable)(void *ctx);
 };
 
-struct exynos_hdmi_overlay_ops {
+struct exynos_mixer_ops {
+       /* manager */
        int (*enable_vblank)(void *ctx, int pipe);
        void (*disable_vblank)(void *ctx);
+
+       /* overlay */
        void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
        void (*win_commit)(void *ctx, int zpos);
        void (*win_disable)(void *ctx, int zpos);
 };
 
-extern struct platform_driver hdmi_driver;
-extern struct platform_driver mixer_driver;
-
-void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
-                                       *display_ops);
-void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
-                                       *manager_ops);
-void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
-                                       *overlay_ops);
-
+void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
+void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
 #endif
index c277a3a445f5a206209dc898ded6f15500b084a7..f92fe4c6174ad163bf250786e77949c9e2d9230e 100644 (file)
@@ -24,6 +24,10 @@ struct exynos_plane {
 
 static const uint32_t formats[] = {
        DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_NV12,
+       DRM_FORMAT_NV12M,
+       DRM_FORMAT_NV12MT,
 };
 
 static int
index 8e1339f9fe1fac6bcfde1a07e46d53f3e6558d00..7b9c153dceb610776f59711d4c5c3c303ff21228 100644 (file)
@@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode)
 static void vidi_apply(struct device *subdrv_dev)
 {
        struct vidi_context *ctx = get_vidi_context(subdrv_dev);
-       struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
+       struct exynos_drm_manager *mgr = ctx->subdrv.manager;
        struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
        struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
        struct vidi_win_data *win_data;
@@ -374,6 +374,13 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = {
        .disable = vidi_win_disable,
 };
 
+static struct exynos_drm_manager vidi_manager = {
+       .pipe           = -1,
+       .ops            = &vidi_manager_ops,
+       .overlay_ops    = &vidi_overlay_ops,
+       .display_ops    = &vidi_display_ops,
+};
+
 static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc)
 {
        struct exynos_drm_private *dev_priv = drm_dev->dev_private;
@@ -425,7 +432,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
        struct vidi_context *ctx = container_of(work, struct vidi_context,
                                        work);
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct exynos_drm_manager *manager = &subdrv->manager;
+       struct exynos_drm_manager *manager = subdrv->manager;
 
        if (manager->pipe < 0)
                return;
@@ -471,7 +478,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev)
 static int vidi_power_on(struct vidi_context *ctx, bool enable)
 {
        struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-       struct device *dev = subdrv->manager.dev;
+       struct device *dev = subdrv->dev;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -611,13 +618,10 @@ static int __devinit vidi_probe(struct platform_device *pdev)
        ctx->raw_edid = (struct edid *)fake_edid_info;
 
        subdrv = &ctx->subdrv;
+       subdrv->dev = dev;
+       subdrv->manager = &vidi_manager;
        subdrv->probe = vidi_subdrv_probe;
        subdrv->remove = vidi_subdrv_remove;
-       subdrv->manager.pipe = -1;
-       subdrv->manager.ops = &vidi_manager_ops;
-       subdrv->manager.overlay_ops = &vidi_overlay_ops;
-       subdrv->manager.display_ops = &vidi_display_ops;
-       subdrv->manager.dev = dev;
 
        mutex_init(&ctx->lock);
 
index 575a8cbd35337b2719195b733485c4d04aee580c..b00353876458577f702f1b104f67bbd3c20915bf 100644 (file)
@@ -40,7 +40,6 @@
 
 #include "exynos_hdmi.h"
 
-#define HDMI_OVERLAY_NUMBER    3
 #define MAX_WIDTH              1920
 #define MAX_HEIGHT             1080
 #define get_hdmi_context(dev)  platform_get_drvdata(to_platform_device(dev))
@@ -1194,7 +1193,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata,
 
 static bool hdmi_is_connected(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
 
        if (val)
@@ -1207,7 +1206,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
                                u8 *edid, int len)
 {
        struct edid *raw_edid;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1275,7 +1274,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
 
 static int hdmi_check_timing(void *ctx, void *timing)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        struct fb_videomode *check_timing = timing;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1312,13 +1311,6 @@ static int hdmi_display_power_on(void *ctx, int mode)
        return 0;
 }
 
-static struct exynos_hdmi_display_ops display_ops = {
-       .is_connected   = hdmi_is_connected,
-       .get_edid       = hdmi_get_edid,
-       .check_timing   = hdmi_check_timing,
-       .power_on       = hdmi_display_power_on,
-};
-
 static void hdmi_set_acr(u32 freq, u8 *acr)
 {
        u32 n, cts;
@@ -1914,7 +1906,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
                                struct drm_display_mode *adjusted_mode)
 {
        struct drm_display_mode *m;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        int index;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1951,7 +1943,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
 
 static void hdmi_mode_set(void *ctx, void *mode)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
        int conf_idx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -1974,7 +1966,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width,
 
 static void hdmi_commit(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1985,7 +1977,7 @@ static void hdmi_commit(void *ctx)
 
 static void hdmi_disable(void *ctx)
 {
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx;
+       struct hdmi_context *hdata = ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
@@ -1996,7 +1988,14 @@ static void hdmi_disable(void *ctx)
        }
 }
 
-static struct exynos_hdmi_manager_ops manager_ops = {
+static struct exynos_hdmi_ops hdmi_ops = {
+       /* display */
+       .is_connected   = hdmi_is_connected,
+       .get_edid       = hdmi_get_edid,
+       .check_timing   = hdmi_check_timing,
+       .power_on       = hdmi_display_power_on,
+
+       /* manager */
        .mode_fixup     = hdmi_mode_fixup,
        .mode_set       = hdmi_mode_set,
        .get_max_resol  = hdmi_get_max_resol,
@@ -2020,7 +2019,7 @@ static void hdmi_hotplug_func(struct work_struct *work)
 static irqreturn_t hdmi_irq_handler(int irq, void *arg)
 {
        struct exynos_drm_hdmi_context *ctx = arg;
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+       struct hdmi_context *hdata = ctx->ctx;
        u32 intc_flag;
 
        intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG);
@@ -2173,7 +2172,7 @@ static int hdmi_runtime_suspend(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __func__);
 
-       hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx);
+       hdmi_resource_poweroff(ctx->ctx);
 
        return 0;
 }
@@ -2184,7 +2183,7 @@ static int hdmi_runtime_resume(struct device *dev)
 
        DRM_DEBUG_KMS("%s\n", __func__);
 
-       hdmi_resource_poweron((struct hdmi_context *)ctx->ctx);
+       hdmi_resource_poweron(ctx->ctx);
 
        return 0;
 }
@@ -2322,8 +2321,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
        hdata->irq = res->start;
 
        /* register specific callbacks to common hdmi. */
-       exynos_drm_display_ops_register(&display_ops);
-       exynos_drm_manager_ops_register(&manager_ops);
+       exynos_hdmi_ops_register(&hdmi_ops);
 
        hdmi_resource_poweron(hdata);
 
@@ -2351,7 +2349,7 @@ err_data:
 static int __devexit hdmi_remove(struct platform_device *pdev)
 {
        struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev);
-       struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx;
+       struct hdmi_context *hdata = ctx->ctx;
 
        DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
index 4d5f41e19527f0514fd63d4d46fb958701247462..e15438c01129249e397a32ae2bea7c15eb10af86 100644 (file)
@@ -37,7 +37,8 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_hdmi.h"
 
-#define HDMI_OVERLAY_NUMBER    3
+#define MIXER_WIN_NR           3
+#define MIXER_DEFAULT_WIN      0
 
 #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
 
@@ -75,16 +76,12 @@ struct mixer_resources {
 };
 
 struct mixer_context {
-       struct fb_videomode     *default_timing;
-       unsigned int            default_win;
-       unsigned int            default_bpp;
        unsigned int            irq;
        int                     pipe;
        bool                    interlace;
-       bool                    vp_enabled;
 
        struct mixer_resources  mixer_res;
-       struct hdmi_win_data    win_data[HDMI_OVERLAY_NUMBER];
+       struct hdmi_win_data    win_data[MIXER_WIN_NR];
 };
 
 static const u8 filter_y_horiz_tap8[] = {
@@ -643,9 +640,9 @@ static void mixer_win_mode_set(void *ctx,
 
        win = overlay->zpos;
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -683,9 +680,9 @@ static void mixer_win_commit(void *ctx, int zpos)
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -706,9 +703,9 @@ static void mixer_win_disable(void *ctx, int zpos)
        DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
        if (win == DEFAULT_ZPOS)
-               win = mixer_ctx->default_win;
+               win = MIXER_DEFAULT_WIN;
 
-       if (win < 0 || win > HDMI_OVERLAY_NUMBER) {
+       if (win < 0 || win > MIXER_WIN_NR) {
                DRM_ERROR("overlay plane[%d] is wrong\n", win);
                return;
        }
@@ -722,9 +719,12 @@ static void mixer_win_disable(void *ctx, int zpos)
        spin_unlock_irqrestore(&res->reg_slock, flags);
 }
 
-static struct exynos_hdmi_overlay_ops overlay_ops = {
+static struct exynos_mixer_ops mixer_ops = {
+       /* manager */
        .enable_vblank          = mixer_enable_vblank,
        .disable_vblank         = mixer_disable_vblank,
+
+       /* overlay */
        .win_mode_set           = mixer_win_mode_set,
        .win_commit             = mixer_win_commit,
        .win_disable            = mixer_win_disable,
@@ -771,8 +771,7 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
 static irqreturn_t mixer_irq_handler(int irq, void *arg)
 {
        struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
-       struct mixer_context *ctx =
-                       (struct mixer_context *)drm_hdmi_ctx->ctx;
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
        struct mixer_resources *res = &ctx->mixer_res;
        u32 val, val_base;
 
@@ -902,7 +901,7 @@ static int mixer_runtime_resume(struct device *dev)
 
        DRM_DEBUG_KMS("resume - start\n");
 
-       mixer_resource_poweron((struct mixer_context *)ctx->ctx);
+       mixer_resource_poweron(ctx->ctx);
 
        return 0;
 }
@@ -913,7 +912,7 @@ static int mixer_runtime_suspend(struct device *dev)
 
        DRM_DEBUG_KMS("suspend - start\n");
 
-       mixer_resource_poweroff((struct mixer_context *)ctx->ctx);
+       mixer_resource_poweroff(ctx->ctx);
 
        return 0;
 }
@@ -926,8 +925,7 @@ static const struct dev_pm_ops mixer_pm_ops = {
 static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
                                 struct platform_device *pdev)
 {
-       struct mixer_context *mixer_ctx =
-                       (struct mixer_context *)ctx->ctx;
+       struct mixer_context *mixer_ctx = ctx->ctx;
        struct device *dev = &pdev->dev;
        struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
        struct resource *res;
@@ -1076,7 +1074,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
                goto fail;
 
        /* register specific callback point to common hdmi. */
-       exynos_drm_overlay_ops_register(&overlay_ops);
+       exynos_mixer_ops_register(&mixer_ops);
 
        mixer_resource_poweron(ctx);
 
@@ -1093,7 +1091,7 @@ static int mixer_remove(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct exynos_drm_hdmi_context *drm_hdmi_ctx =
                                        platform_get_drvdata(pdev);
-       struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
+       struct mixer_context *ctx = drm_hdmi_ctx->ctx;
 
        dev_info(dev, "remove successful\n");
 
index dfa55e7478fb88501bdb73d29edbd14b5f8eecaa..ae8a64f9f8453266326803432156c81219d246ab 100644 (file)
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores,
                "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
 
 int i915_enable_rc6 __read_mostly = -1;
-module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
+module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
 MODULE_PARM_DESC(i915_enable_rc6,
                "Enable power-saving render C-state 6. "
                "Different stages can be selected via bitmask values "
index 4c65c639f7721d315a1b5875fe4f32478471fab3..0e3c6acde955d47e95576261acee362d36f12e8e 100644 (file)
@@ -1493,6 +1493,7 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
 {
        list_del_init(&obj->ring_list);
        obj->last_rendering_seqno = 0;
+       obj->last_fenced_seqno = 0;
 }
 
 static void
@@ -1521,6 +1522,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
        BUG_ON(!list_empty(&obj->gpu_write_list));
        BUG_ON(!obj->active);
        obj->ring = NULL;
+       obj->last_fenced_ring = NULL;
 
        i915_gem_object_move_off_active(obj);
        obj->fenced_gpu_access = false;
index 2abf4eb9403928be8cfb237910090cca0e8a4840..b4bb1ef77ddc967d060d0de226ffb1cf80f26468 100644 (file)
 #define  GT_FIFO_FREE_ENTRIES                  0x120008
 #define    GT_FIFO_NUM_RESERVED_ENTRIES                20
 
+#define GEN6_UCGCTL1                           0x9400
+# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE               (1 << 5)
+
 #define GEN6_UCGCTL2                           0x9404
 # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE               (1 << 13)
 # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE              (1 << 12)
index 91b35fd1db8c81ee06984de0aaae88824929cddd..bae38acf44dc4396ce7bb7af53162d435af9ec46 100644 (file)
@@ -2244,6 +2244,33 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        return 0;
 }
 
+static int
+intel_finish_fb(struct drm_framebuffer *old_fb)
+{
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
+       struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+       bool was_interruptible = dev_priv->mm.interruptible;
+       int ret;
+
+       wait_event(dev_priv->pending_flip_queue,
+                  atomic_read(&dev_priv->mm.wedged) ||
+                  atomic_read(&obj->pending_flip) == 0);
+
+       /* Big Hammer, we also need to ensure that any pending
+        * MI_WAIT_FOR_EVENT inside a user batch buffer on the
+        * current scanout is retired before unpinning the old
+        * framebuffer.
+        *
+        * This should only fail upon a hung GPU, in which case we
+        * can safely continue.
+        */
+       dev_priv->mm.interruptible = false;
+       ret = i915_gem_object_finish_gpu(obj);
+       dev_priv->mm.interruptible = was_interruptible;
+
+       return ret;
+}
+
 static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                    struct drm_framebuffer *old_fb)
@@ -2282,25 +2309,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                return ret;
        }
 
-       if (old_fb) {
-               struct drm_i915_private *dev_priv = dev->dev_private;
-               struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
-
-               wait_event(dev_priv->pending_flip_queue,
-                          atomic_read(&dev_priv->mm.wedged) ||
-                          atomic_read(&obj->pending_flip) == 0);
-
-               /* Big Hammer, we also need to ensure that any pending
-                * MI_WAIT_FOR_EVENT inside a user batch buffer on the
-                * current scanout is retired before unpinning the old
-                * framebuffer.
-                *
-                * This should only fail upon a hung GPU, in which case we
-                * can safely continue.
-                */
-               ret = i915_gem_object_finish_gpu(obj);
-               (void) ret;
-       }
+       if (old_fb)
+               intel_finish_fb(old_fb);
 
        ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
                                         LEAVE_ATOMIC_MODE_SET);
@@ -3371,6 +3381,23 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
        struct drm_device *dev = crtc->dev;
 
+       /* Flush any pending WAITs before we disable the pipe. Note that
+        * we need to drop the struct_mutex in order to acquire it again
+        * during the lowlevel dpms routines around a couple of the
+        * operations. It does not look trivial nor desirable to move
+        * that locking higher. So instead we leave a window for the
+        * submission of further commands on the fb before we can actually
+        * disable it. This race with userspace exists anyway, and we can
+        * only rely on the pipe being disabled by userspace after it
+        * receives the hotplug notification and has flushed any pending
+        * batches.
+        */
+       if (crtc->fb) {
+               mutex_lock(&dev->struct_mutex);
+               intel_finish_fb(crtc->fb);
+               mutex_unlock(&dev->struct_mutex);
+       }
+
        crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
        assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
        assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
@@ -8529,6 +8556,10 @@ static void gen6_init_clock_gating(struct drm_device *dev)
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
 
+       I915_WRITE(GEN6_UCGCTL1,
+                  I915_READ(GEN6_UCGCTL1) |
+                  GEN6_BLBUNIT_CLOCK_GATE_DISABLE);
+
        /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
         * gating disable must be set.  Failure to set it results in
         * flickering pixels due to Z write ordering failures after
index 110552ff302c1dea71360dfc84da622d1cec1785..4b637919f74f6359b64fc996c04a2f2e6a353def 100644 (file)
@@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
        return (max_link_clock * max_lanes * 8) / 10;
 }
 
+static bool
+intel_dp_adjust_dithering(struct intel_dp *intel_dp,
+                         struct drm_display_mode *mode,
+                         struct drm_display_mode *adjusted_mode)
+{
+       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
+       int max_lanes = intel_dp_max_lane_count(intel_dp);
+       int max_rate, mode_rate;
+
+       mode_rate = intel_dp_link_required(mode->clock, 24);
+       max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
+
+       if (mode_rate > max_rate) {
+               mode_rate = intel_dp_link_required(mode->clock, 18);
+               if (mode_rate > max_rate)
+                       return false;
+
+               if (adjusted_mode)
+                       adjusted_mode->private_flags
+                               |= INTEL_MODE_DP_FORCE_6BPC;
+
+               return true;
+       }
+
+       return true;
+}
+
 static int
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
        struct intel_dp *intel_dp = intel_attached_dp(connector);
-       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
-       int max_lanes = intel_dp_max_lane_count(intel_dp);
-       int max_rate, mode_rate;
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
                if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
@@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
                        return MODE_PANEL;
        }
 
-       mode_rate = intel_dp_link_required(mode->clock, 24);
-       max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
-
-       if (mode_rate > max_rate) {
-                       mode_rate = intel_dp_link_required(mode->clock, 18);
-                       if (mode_rate > max_rate)
-                               return MODE_CLOCK_HIGH;
-                       else
-                               mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC;
-       }
+       if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
+               return MODE_CLOCK_HIGH;
 
        if (mode->clock < 10000)
                return MODE_CLOCK_LOW;
@@ -672,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
        int lane_count, clock;
        int max_lane_count = intel_dp_max_lane_count(intel_dp);
        int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
-       int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+       int bpp;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
@@ -686,6 +702,11 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                mode->clock = intel_dp->panel_fixed_mode->clock;
        }
 
+       if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
+               return false;
+
+       bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
+
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
index 601c86e664afd237875aefc43fe65a0671930cb5..8fdc9570021853e3c94fec296a7bca3e14a60b7b 100644 (file)
@@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev)
                bus->has_gpio = intel_gpio_setup(bus, i);
 
                /* XXX force bit banging until GMBUS is fully debugged */
-               if (bus->has_gpio && IS_GEN2(dev))
+               if (bus->has_gpio)
                        bus->force_bit = true;
        }
 
index e25581a9f60f3d80ea3cbd60ab282373da7bfe8b..f75806e5bff5c62273ddaee7d5f94bd15cb860e8 100644 (file)
@@ -1038,7 +1038,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
         * of the buffer.
         */
        ring->effective_size = ring->size;
-       if (IS_I830(ring->dev))
+       if (IS_I830(ring->dev) || IS_845G(ring->dev))
                ring->effective_size -= 128;
 
        return 0;
index a464771a724070a229e917d7b7e5e249d1058845..e90dfb625c4201137d1b8a893fa99342904059d4 100644 (file)
@@ -95,7 +95,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
        /* must disable */
        sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
        sprctl |= SPRITE_ENABLE;
-       sprctl |= SPRITE_DEST_KEY;
 
        /* Sizes are 0 based */
        src_w--;
index e607c4d7dd98bbccd9a709ab908b0c2c5b26a4b9..2d39f9977e005dd2ba5f8e53930569dc461db109 100644 (file)
@@ -230,6 +230,10 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
        if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
                return;
 
+       /* some R4xx chips have the wrong frev */
+       if (rdev->family <= CHIP_RV410)
+               frev = 1;
+
        switch (frev) {
        case 1:
                switch (crev) {
index 81801c176aa5c8b4cc45644df5c5a7a471128cd3..fe33d35dae8c6ca851103e476426e12194d7d4b1 100644 (file)
@@ -2553,7 +2553,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev)
         * or the chip could hang on a subsequent access
         */
        if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) {
-               udelay(5000);
+               mdelay(5);
        }
 
        /* This function is required to workaround a hardware bug in some (all?)
index 391bd2636a8054bb5e102388060e54a1b10f9c97..de71243b591ff037dc9555bd83d7b85cc8657eda 100644 (file)
@@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev)
                /* r7xx asics need to soft reset RLC before halting */
                WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
                RREG32(SRBM_SOFT_RESET);
-               udelay(15000);
+               mdelay(15);
                WREG32(SRBM_SOFT_RESET, 0);
                RREG32(SRBM_SOFT_RESET);
        }
index 84c546250955bfc354456dc858f839c6bb27fcfa..75ed17c96115f30bca7aa4c7ca9fe7f65c035cb9 100644 (file)
@@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
        fw_data = (const __be32 *)dev_priv->me_fw->data;
@@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
        fw_data = (const __be32 *)dev_priv->pfp_fw->data;
@@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
 
        RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
        RADEON_READ(R600_GRBM_SOFT_RESET);
-       DRM_UDELAY(15000);
+       mdelay(15);
        RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
 
index 6ae0c75f016acfaaf7bcb705503c187a563f7198..9c6b29a4192773087b1db8b62326e76bb2d971d2 100644 (file)
@@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp &= ~(R300_SCLK_FORCE_VAP);
                                tmp |= RADEON_SCLK_FORCE_CP;
                                WREG32_PLL(RADEON_SCLK_CNTL, tmp);
-                               udelay(15000);
+                               mdelay(15);
 
                                tmp = RREG32_PLL(R300_SCLK_CNTL2);
                                tmp &= ~(R300_SCLK_FORCE_TCL |
@@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                        tmp |= (RADEON_ENGIN_DYNCLK_MODE |
                                (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
                        WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
                        tmp |= RADEON_SCLK_DYN_START_CNTL;
                        WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
                           to lockup randomly, leave them as set by BIOS.
@@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        tmp |= RADEON_SCLK_MORE_FORCEON;
                                }
                                WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
-                               udelay(15000);
+                               mdelay(15);
                        }
 
                        /* RV200::A11 A12, RV250::A11 A12 */
@@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp |= RADEON_TCL_BYPASS_DISABLE;
                                WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
                        }
-                       udelay(15000);
+                       mdelay(15);
 
                        /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
                        tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                RADEON_PIXCLK_TMDS_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
 
                        tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
                        tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
                                RADEON_PIXCLK_DAC_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
-                       udelay(15000);
+                       mdelay(15);
                }
        } else {
                /* Turn everything OFF (ForceON to everything) */
@@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                        }
                        WREG32_PLL(RADEON_SCLK_CNTL, tmp);
 
-                       udelay(16000);
+                       mdelay(16);
 
                        if ((rdev->family == CHIP_R300) ||
                            (rdev->family == CHIP_R350)) {
@@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                        R300_SCLK_FORCE_GA |
                                        R300_SCLK_FORCE_CBA);
                                WREG32_PLL(R300_SCLK_CNTL2, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        if (rdev->flags & RADEON_IS_IGP) {
@@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp &= ~(RADEON_FORCEON_MCLKA |
                                         RADEON_FORCEON_YCLKA);
                                WREG32_PLL(RADEON_MCLK_CNTL, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        if ((rdev->family == CHIP_RV200) ||
@@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
                                tmp |= RADEON_SCLK_MORE_FORCEON;
                                WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
-                               udelay(16000);
+                               mdelay(16);
                        }
 
                        tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
                                 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
 
                        WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
-                       udelay(16000);
+                       mdelay(16);
 
                        tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
                        tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
index 81fc100be7e18c321c088bc787e1154de96e11e3..2cad9fde92fca9277983dfdadc48948d66f3fb27 100644 (file)
@@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
                                        case 4:
                                                val = RBIOS16(index);
                                                index += 2;
-                                               udelay(val * 1000);
+                                               mdelay(val);
                                                break;
                                        case 6:
                                                slave_addr = id & 0xff;
@@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
                                        udelay(150);
                                        break;
                                case 2:
-                                       udelay(1000);
+                                       mdelay(1);
                                        break;
                                case 3:
                                        while (tmp--) {
@@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset)
                                                /*mclk_cntl |= 0x00001111;*//* ??? */
                                                WREG32_PLL(RADEON_MCLK_CNTL,
                                                           mclk_cntl);
-                                               udelay(10000);
+                                               mdelay(10);
 #endif
                                                WREG32_PLL
                                                    (RADEON_CLK_PWRMGT_CNTL,
                                                     tmp &
                                                     ~RADEON_CG_NO1_DEBUG_0);
-                                               udelay(10000);
+                                               mdelay(10);
                                        }
                                        break;
                                default:
index 85bcfc8923a789bf73101a1c5ef7cadc9ec1300f..3edec1c198e3145addb0b47bbafdf3cf2abd1e49 100644 (file)
@@ -900,6 +900,10 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
        struct radeon_i2c_chan *i2c;
        int ret;
 
+       /* don't add the mm_i2c bus unless hw_i2c is enabled */
+       if (rec->mm_i2c && (radeon_hw_i2c == 0))
+               return NULL;
+
        i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
        if (i2c == NULL)
                return NULL;
index 2f46e0c8df53256a9bf5d6271b55141be2f8b35a..42db254f6bb04e13f86c8ba238e6be7685a20578 100644 (file)
@@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
                lvds_pll_cntl |= RADEON_LVDS_PLL_EN;
                WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
-               udelay(1000);
+               mdelay(1);
 
                lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL);
                lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
@@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                                  (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT));
                if (is_mac)
                        lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                break;
        case DRM_MODE_DPMS_STANDBY:
@@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode)
                        WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                        lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
                }
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
                WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
-               udelay(panel_pwr_delay * 1000);
+               mdelay(panel_pwr_delay);
                break;
        }
 
@@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
 
        WREG32(RADEON_DAC_MACRO_CNTL, tmp);
 
-       udelay(2000);
+       mdelay(2);
 
        if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT)
                found = connector_status_connected;
@@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
        tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
        WREG32(RADEON_DAC_CNTL2, tmp);
 
-       udelay(10000);
+       mdelay(10);
 
        if (ASIC_IS_R300(rdev)) {
                if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B)
index 031aaaf79ac2da2c2972dfbadade2530877a55cb..b6d8608375cde6b0063796d83ae763b4bd1b14db 100644 (file)
@@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
         * for locking on FreeBSD.
         */
        if (cmdbuf->size) {
-               kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL);
+               kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL);
                if (kcmd_addr == NULL)
                        return -ENOMEM;
 
@@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_
                cmdbuf->vb_addr = kvb_addr;
        }
        if (cmdbuf->nbox) {
-               kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect),
-                                   GFP_KERNEL);
+               kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect),
+                                         GFP_KERNEL);
                if (kbox_addr == NULL) {
                        ret = -ENOMEM;
                        goto done;
index 34aebb8cd080602479de04d496ff3c5b9ee4b8f0..3c843cd725fac0ec0a7f4c63310f47ad942da0a0 100644 (file)
@@ -95,7 +95,8 @@ static int __devinit da9052_onkey_probe(struct platform_device *pdev)
        input_dev = input_allocate_device();
        if (!onkey || !input_dev) {
                dev_err(&pdev->dev, "Failed to allocate memory\n");
-               return -ENOMEM;
+               error = -ENOMEM;
+               goto err_free_mem;
        }
 
        onkey->input = input_dev;
index d2c0db159b18dfc364c2ff7fc036863ef2de9614..479011004a111dcf41cc344356da29e3deb74902 100644 (file)
@@ -486,7 +486,6 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
        unsigned char *packet = psmouse->packet;
 
        input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
-       input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
        input_mt_report_pointer_emulation(dev, true);
        input_sync(dev);
 }
@@ -967,6 +966,7 @@ static int elantech_set_input_params(struct psmouse *psmouse)
        if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width))
                return -1;
 
+       __set_bit(INPUT_PROP_POINTER, dev->propbit);
        __set_bit(EV_KEY, dev->evbit);
        __set_bit(EV_ABS, dev->evbit);
        __clear_bit(EV_REL, dev->evbit);
@@ -1017,7 +1017,9 @@ static int elantech_set_input_params(struct psmouse *psmouse)
                         */
                        psmouse_warn(psmouse, "couldn't query resolution data.\n");
                }
-
+               /* v4 is clickpad, with only one button. */
+               __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
+               __clear_bit(BTN_RIGHT, dev->keybit);
                __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
                /* For X to recognize me as touchpad. */
                input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0);
@@ -1245,6 +1247,8 @@ static void elantech_disconnect(struct psmouse *psmouse)
  */
 static int elantech_reconnect(struct psmouse *psmouse)
 {
+       psmouse_reset(psmouse);
+
        if (elantech_detect(psmouse, 0))
                return -1;
 
@@ -1324,6 +1328,8 @@ int elantech_init(struct psmouse *psmouse)
        if (!etd)
                return -ENOMEM;
 
+       psmouse_reset(psmouse);
+
        etd->parity[0] = 1;
        for (i = 1; i < 256; i++)
                etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
index a9ad8e1402be217786574e88146d6e5d652a1e8e..39fe9b737cae5c57aca9a588247038cb75ff375c 100644 (file)
@@ -12,9 +12,9 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
+#include <linux/gpio.h>
 #include <linux/gpio_mouse.h>
 
-#include <asm/gpio.h>
 
 /*
  * Timer function which is run every scan_ms ms when the device is opened.
index a977bfaa6821faef1c2993c919f77a854b9a03d8..661a0ca3b3d6939df7b11efd2576f4eb8dcc55f5 100644 (file)
@@ -741,6 +741,14 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
                        }
                } else {
                        /* SFAC packet */
+                       if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) ==
+                               FSP_PB0_LBTN) {
+                               /* On-pad click in SFAC mode should be handled
+                                * by userspace.  On-pad clicks in MFMC mode
+                                * are real clickpad clicks, and not ignored.
+                                */
+                               packet[0] &= ~FSP_PB0_LBTN;
+                       }
 
                        /* no multi-finger information */
                        ad->last_mt_fgr = 0;
index 22b218018137d964fdae5987addd66a1b7272320..f3102494237d207ecf5639d11d78e36d09e78050 100644 (file)
@@ -304,7 +304,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
                return 0;
 
        if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
-               printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n");
+               psmouse_warn(psmouse, "failed to get extended button data\n");
                button_info = 0;
        }
 
@@ -326,16 +326,18 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 
        error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
        if (error) {
-               printk(KERN_ERR
-                       "trackpoint.c: failed to create sysfs attributes, error: %d\n",
-                       error);
+               psmouse_err(psmouse,
+                           "failed to create sysfs attributes, error: %d\n",
+                           error);
                kfree(psmouse->private);
                psmouse->private = NULL;
                return -1;
        }
 
-       printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
-               firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f);
+       psmouse_info(psmouse,
+                    "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
+                    firmware_id,
+                    (button_info & 0xf0) >> 4, button_info & 0x0f);
 
        return 0;
 }
index 6c6f6d8ea9b413d68b97b47c72e6d1e192e70e05..f7eda3d00fadb46216f09de8eaa9d7c911350d97 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * drivers/input/touchscreen/tps6507x_ts.c
- *
  * Touchscreen driver for the tps6507x chip.
  *
  * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com)
@@ -376,4 +374,4 @@ module_platform_driver(tps6507x_ts_driver);
 MODULE_AUTHOR("Todd Fischer <todd.fischer@ridgerun.com>");
 MODULE_DESCRIPTION("TPS6507x - TouchScreen driver");
 MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tps6507x-tsc");
+MODULE_ALIAS("platform:tps6507x-ts");
index 3d0dfa7a89a2d683c8ccdbe76eedd02260550cba..97e73e555d112c8762b7934bd9892d39f5c6e4ce 100644 (file)
@@ -539,9 +539,6 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
        bitmap->events_cleared = bitmap->mddev->events;
        sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
 
-       bitmap->flags |= BITMAP_HOSTENDIAN;
-       sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN);
-
        kunmap_atomic(sb);
 
        return 0;
@@ -1788,7 +1785,9 @@ int bitmap_load(struct mddev *mddev)
                 * re-add of a missing device */
                start = mddev->recovery_cp;
 
+       mutex_lock(&mddev->bitmap_info.mutex);
        err = bitmap_init_from_disk(bitmap, start);
+       mutex_unlock(&mddev->bitmap_info.mutex);
 
        if (err)
                goto out;
index d35e4c991e38262425cf4495ed6fe98676210ef8..15dd59b84e94442c50ae164cb2ec1c130a74bc52 100644 (file)
@@ -1712,6 +1712,7 @@ static int process_checks(struct r1bio *r1_bio)
        struct r1conf *conf = mddev->private;
        int primary;
        int i;
+       int vcnt;
 
        for (primary = 0; primary < conf->raid_disks * 2; primary++)
                if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
@@ -1721,9 +1722,9 @@ static int process_checks(struct r1bio *r1_bio)
                        break;
                }
        r1_bio->read_disk = primary;
+       vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
        for (i = 0; i < conf->raid_disks * 2; i++) {
                int j;
-               int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9);
                struct bio *pbio = r1_bio->bios[primary];
                struct bio *sbio = r1_bio->bios[i];
                int size;
index fff782189e48f017f3407bb93ec7847a1fe367fd..c8dbb84d53579ab3e5c9ebc012a06cdb5205058f 100644 (file)
@@ -1788,6 +1788,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
        struct r10conf *conf = mddev->private;
        int i, first;
        struct bio *tbio, *fbio;
+       int vcnt;
 
        atomic_set(&r10_bio->remaining, 1);
 
@@ -1802,10 +1803,10 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
        first = i;
        fbio = r10_bio->devs[i].bio;
 
+       vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9);
        /* now find blocks with errors */
        for (i=0 ; i < conf->copies ; i++) {
                int  j, d;
-               int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
 
                tbio = r10_bio->devs[i].bio;
 
@@ -1871,7 +1872,6 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
         */
        for (i = 0; i < conf->copies; i++) {
                int j, d;
-               int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
 
                tbio = r10_bio->devs[i].repl_bio;
                if (!tbio || !tbio->bi_end_io)
index 94eb05b1afdfd2bcab367a6e6fa6dbab0667dca9..58fc65f5c8176d130bef3795ccb5163328489be6 100644 (file)
@@ -106,16 +106,14 @@ static int mtdchar_open(struct inode *inode, struct file *file)
        }
 
        if (mtd->type == MTD_ABSENT) {
-               put_mtd_device(mtd);
                ret = -ENODEV;
-               goto out;
+               goto out1;
        }
 
        mtd_ino = iget_locked(mnt->mnt_sb, devnum);
        if (!mtd_ino) {
-               put_mtd_device(mtd);
                ret = -ENOMEM;
-               goto out;
+               goto out1;
        }
        if (mtd_ino->i_state & I_NEW) {
                mtd_ino->i_private = mtd;
@@ -127,23 +125,25 @@ static int mtdchar_open(struct inode *inode, struct file *file)
 
        /* You can't open it RW if it's not a writeable device */
        if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
-               iput(mtd_ino);
-               put_mtd_device(mtd);
                ret = -EACCES;
-               goto out;
+               goto out2;
        }
 
        mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
        if (!mfi) {
-               iput(mtd_ino);
-               put_mtd_device(mtd);
                ret = -ENOMEM;
-               goto out;
+               goto out2;
        }
        mfi->ino = mtd_ino;
        mfi->mtd = mtd;
        file->private_data = mfi;
+       mutex_unlock(&mtd_mutex);
+       return 0;
 
+out2:
+       iput(mtd_ino);
+out1:
+       put_mtd_device(mtd);
 out:
        mutex_unlock(&mtd_mutex);
        simple_release_fs(&mnt, &count);
index 215eb2536b1e97878f0e9c891a93762f8d349be2..2504ab00558971d15f77569593e7d8756ede1761 100644 (file)
@@ -118,15 +118,13 @@ void ath9k_ps_restore(struct ath_softc *sc)
        if (--sc->ps_usecount != 0)
                goto unlock;
 
-       if (sc->ps_flags & PS_WAIT_FOR_TX_ACK)
-               goto unlock;
-
-       if (sc->ps_idle)
+       if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
                mode = ATH9K_PM_FULL_SLEEP;
        else if (sc->ps_enabled &&
                 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
                              PS_WAIT_FOR_CAB |
-                             PS_WAIT_FOR_PSPOLL_DATA)))
+                             PS_WAIT_FOR_PSPOLL_DATA |
+                             PS_WAIT_FOR_TX_ACK)))
                mode = ATH9K_PM_NETWORK_SLEEP;
        else
                goto unlock;
index fc9901e027c16d521bc59a3570036ba4808bc0f0..90cc5e77265058cfa894cdc5111e34ee542774a2 100644 (file)
@@ -1062,11 +1062,6 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
 
        set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
 
-       /*
-        * Register the extra components.
-        */
-       rt2x00rfkill_register(rt2x00dev);
-
        return 0;
 }
 
@@ -1210,6 +1205,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
        rt2x00link_register(rt2x00dev);
        rt2x00leds_register(rt2x00dev);
        rt2x00debug_register(rt2x00dev);
+       rt2x00rfkill_register(rt2x00dev);
 
        return 0;
 
index 510023554e5f43ba0105a2cd5de09e8987b861dd..e54488db0e10178bfb820da5d23eb0e2a54591f8 100644 (file)
@@ -838,7 +838,10 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
        __le16 fc = hdr->frame_control;
 
        txrate = ieee80211_get_tx_rate(hw, info);
-       tcb_desc->hw_rate = txrate->hw_value;
+       if (txrate)
+               tcb_desc->hw_rate = txrate->hw_value;
+       else
+               tcb_desc->hw_rate = 0;
 
        if (ieee80211_is_data(fc)) {
                /*
index 07dd38efe62a01580c9debe210fb2d38c8ddd50e..288b035a3579b06b2dfba78c17369416b4ab2a44 100644 (file)
@@ -912,8 +912,13 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
        memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
        ring = &rtlpci->tx_ring[BEACON_QUEUE];
        pskb = __skb_dequeue(&ring->queue);
-       if (pskb)
+       if (pskb) {
+               struct rtl_tx_desc *entry = &ring->desc[ring->idx];
+               pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops->get_desc(
+                                (u8 *) entry, true, HW_DESC_TXBUFF_ADDR),
+                                pskb->len, PCI_DMA_TODEVICE);
                kfree_skb(pskb);
+       }
 
        /*NB: the beacon data buffer must be 32-bit aligned. */
        pskb = ieee80211_beacon_get(hw, mac->vif);
index 4898c502974db606bf725ed0664318f0655ab7f8..480862c07f921668e803694a37ef702f19d34a8d 100644 (file)
@@ -91,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
        u8 tid;
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-       static int header_print;
 
        rtlpriv->dm.dm_initialgain_enable = true;
        rtlpriv->dm.dm_flag = 0;
@@ -171,10 +170,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
        for (tid = 0; tid < 8; tid++)
                skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
 
-       /* Only load firmware for first MAC */
-       if (header_print)
-               return 0;
-
        /* for firmware buf */
        rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
        if (!rtlpriv->rtlhal.pfirmware) {
@@ -186,7 +181,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->max_fw_size = 0x8000;
        pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
        pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
-       header_print++;
 
        /* request fw */
        err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
index 2e1e352864bb88ad33489402aee1f19ef2aa4154..d04dbda13f5a3bd699e6265490736da54adc2702 100644 (file)
@@ -124,46 +124,38 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request,
        return status;
 }
 
-static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len)
+static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len)
 {
+       struct device *dev = rtlpriv->io.dev;
+       struct usb_device *udev = to_usb_device(dev);
        u8 request;
        u16 wvalue;
        u16 index;
-       u32 *data;
-       u32 ret;
+       __le32 *data = &rtlpriv->usb_data[rtlpriv->usb_data_index];
 
-       data = kmalloc(sizeof(u32), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
        request = REALTEK_USB_VENQT_CMD_REQ;
        index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */
 
        wvalue = (u16)addr;
        _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len);
-       ret = le32_to_cpu(*data);
-       kfree(data);
-       return ret;
+       if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT)
+               rtlpriv->usb_data_index = 0;
+       return le32_to_cpu(*data);
 }
 
 static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       struct device *dev = rtlpriv->io.dev;
-
-       return (u8)_usb_read_sync(to_usb_device(dev), addr, 1);
+       return (u8)_usb_read_sync(rtlpriv, addr, 1);
 }
 
 static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       struct device *dev = rtlpriv->io.dev;
-
-       return (u16)_usb_read_sync(to_usb_device(dev), addr, 2);
+       return (u16)_usb_read_sync(rtlpriv, addr, 2);
 }
 
 static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
-       struct device *dev = rtlpriv->io.dev;
-
-       return _usb_read_sync(to_usb_device(dev), addr, 4);
+       return _usb_read_sync(rtlpriv, addr, 4);
 }
 
 static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val,
@@ -955,6 +947,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
                return -ENOMEM;
        }
        rtlpriv = hw->priv;
+       rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32),
+                                   GFP_KERNEL);
+       if (!rtlpriv->usb_data)
+               return -ENOMEM;
+       rtlpriv->usb_data_index = 0;
        init_completion(&rtlpriv->firmware_loading_complete);
        SET_IEEE80211_DEV(hw, &intf->dev);
        udev = interface_to_usbdev(intf);
@@ -1025,6 +1022,7 @@ void rtl_usb_disconnect(struct usb_interface *intf)
        /* rtl_deinit_rfkill(hw); */
        rtl_usb_deinit(hw);
        rtl_deinit_core(hw);
+       kfree(rtlpriv->usb_data);
        rtlpriv->cfg->ops->deinit_sw_leds(hw);
        rtlpriv->cfg->ops->deinit_sw_vars(hw);
        _rtl_usb_io_handler_release(hw);
index b591614c3b9bb79c7b6e00ec6fe48cb8b06c480b..28ebc69218a3e03251268325edbecdf620ce0103 100644 (file)
@@ -67,7 +67,7 @@
 #define QOS_QUEUE_NUM                          4
 #define RTL_MAC80211_NUM_QUEUE                 5
 #define REALTEK_USB_VENQT_MAX_BUF_SIZE         254
-
+#define RTL_USB_MAX_RX_COUNT                   100
 #define QBSS_LOAD_SIZE                         5
 #define MAX_WMMELE_LENGTH                      64
 
@@ -1629,6 +1629,10 @@ struct rtl_priv {
           interface or hardware */
        unsigned long status;
 
+       /* data buffer pointer for USB reads */
+       __le32 *usb_data;
+       int usb_data_index;
+
        /*This must be the last item so
           that it points to the data allocated
           beyond  this structure like:
index 358094f0433d41c0fbe21360a24e9a475d95e3da..18d08f5db53adb46d832222357df9d81d5058f11 100644 (file)
@@ -529,6 +529,7 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
        return 0;
 out:
        d_genocide(root);
+       shrink_dcache_parent(root);
        dput(root);
        return -ENOMEM;
 }
index 3963116083aeae56fdb3aa9056e86daf8200ed9c..e478de4e5d564e936302d753e65ac4e52768b3a7 100644 (file)
@@ -85,7 +85,7 @@ struct drm_exynos_gem_mmap {
 struct drm_exynos_vidi_connection {
        unsigned int connection;
        unsigned int extensions;
-       uint64_t *edid;
+       uint64_t edid;
 };
 
 struct drm_exynos_plane_set_zpos {
@@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos {
 /* memory type definitions. */
 enum e_drm_exynos_gem_mem_type {
        /* Physically Non-Continuous memory. */
-       EXYNOS_BO_NONCONTIG     = 1 << 0
+       EXYNOS_BO_NONCONTIG     = 1 << 0,
+       EXYNOS_BO_MASK          = EXYNOS_BO_NONCONTIG
 };
 
 #define DRM_EXYNOS_GEM_CREATE          0x00
index bff29c58da23013e5e1e19f0cdeaf2ad45d602fc..7810406f3d8021c0d07049aace417ea82a67f862 100644 (file)
@@ -263,6 +263,11 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
        d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS;
 }
 
+static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
+{
+       return d->hwirq;
+}
+
 /**
  * struct irq_chip - hardware interrupt chip descriptor
  *
index ead4a4215797b81c7a35baed6b428026d2039e00..c65740d76e663a35da56f3e680835d8349e8f9dd 100644 (file)
@@ -42,12 +42,6 @@ struct of_device_id;
 /* Number of irqs reserved for a legacy isa controller */
 #define NUM_ISA_INTERRUPTS     16
 
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
 /**
  * struct irq_domain_ops - Methods for irq_domain objects
  * @match: Match an interrupt controller device node to a host, returns
@@ -104,6 +98,9 @@ struct irq_domain {
                        unsigned int size;
                        unsigned int *revmap;
                } linear;
+               struct {
+                       unsigned int max_irq;
+               } nomap;
                struct radix_tree_root tree;
        } revmap_data;
        const struct irq_domain_ops *ops;
@@ -126,6 +123,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
                                         const struct irq_domain_ops *ops,
                                         void *host_data);
 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+                                        unsigned int max_irq,
                                         const struct irq_domain_ops *ops,
                                         void *host_data);
 struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
@@ -134,7 +132,6 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
 
 extern struct irq_domain *irq_find_host(struct device_node *node);
 extern void irq_set_default_host(struct irq_domain *host);
-extern void irq_set_virq_count(unsigned int count);
 
 static inline struct irq_domain *irq_domain_add_legacy_isa(
                                struct device_node *of_node,
@@ -146,7 +143,6 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
 }
 extern struct irq_domain *irq_find_host(struct device_node *node);
 extern void irq_set_default_host(struct irq_domain *host);
-extern void irq_set_virq_count(unsigned int count);
 
 
 extern unsigned int irq_create_mapping(struct irq_domain *host,
index f549adccc94c569801f4181bacd84e87f0743725..1bc898b14a8070ba0c8aab847157fbe90e8ca619 100644 (file)
@@ -287,7 +287,17 @@ extern unsigned int ip6t_do_table(struct sk_buff *skb,
                                  struct xt_table *table);
 
 /* Check for an extension */
-extern int ip6t_ext_hdr(u8 nexthdr);
+static inline int
+ip6t_ext_hdr(u8 nexthdr)
+{      return (nexthdr == IPPROTO_HOPOPTS) ||
+              (nexthdr == IPPROTO_ROUTING) ||
+              (nexthdr == IPPROTO_FRAGMENT) ||
+              (nexthdr == IPPROTO_ESP) ||
+              (nexthdr == IPPROTO_AH) ||
+              (nexthdr == IPPROTO_NONE) ||
+              (nexthdr == IPPROTO_DSTOPTS);
+}
+
 /* find specified header and get offset to it */
 extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
                         int target, unsigned short *fragoff);
index 33370271b8b2c43ac65925619d15305d27a7018c..70a3f8d49118599510af86a6ef1022a0c064c850 100644 (file)
@@ -481,6 +481,7 @@ struct sk_buff {
        union {
                __u32           mark;
                __u32           dropcount;
+               __u32           avail_size;
        };
 
        sk_buff_data_t          transport_header;
@@ -1365,6 +1366,18 @@ static inline int skb_tailroom(const struct sk_buff *skb)
        return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail;
 }
 
+/**
+ *     skb_availroom - bytes at buffer end
+ *     @skb: buffer to check
+ *
+ *     Return the number of bytes of free space at the tail of an sk_buff
+ *     allocated by sk_stream_alloc()
+ */
+static inline int skb_availroom(const struct sk_buff *skb)
+{
+       return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
+}
+
 /**
  *     skb_reserve - adjust headroom
  *     @skb: buffer to alter
index e5fa50345516837d035650183aebefc7f0633d8b..7f480db60231a714b9e520f3a16856c5d4e4a5e1 100644 (file)
@@ -210,6 +210,12 @@ typedef u32 phys_addr_t;
 
 typedef phys_addr_t resource_size_t;
 
+/*
+ * This type is the placeholder for a hardware interrupt number. It has to be
+ * big enough to enclose whatever representation is used by a given platform.
+ */
+typedef unsigned long irq_hw_number_t;
+
 typedef struct {
        int counter;
 } atomic_t;
index 9c3120dca294ddc41d2a131540d8135cf001de89..b572f80bdfd527d10a9793047c6d2f7c14f0d685 100644 (file)
@@ -47,6 +47,8 @@
  */
 #define VGA_DEFAULT_DEVICE     (NULL)
 
+struct pci_dev;
+
 /* For use by clients */
 
 /**
index 344b0f972828f4167393948c4263a628309ca7c6..d47e523c9d83387460f905414952d81c54b8361e 100644 (file)
@@ -92,6 +92,7 @@ enum {
        HCI_SERVICE_CACHE,
        HCI_LINK_KEYS,
        HCI_DEBUG_KEYS,
+       HCI_UNREGISTER,
 
        HCI_LE_SCAN,
        HCI_SSP_ENABLED,
@@ -1327,8 +1328,8 @@ struct sockaddr_hci {
 #define HCI_DEV_NONE   0xffff
 
 #define HCI_CHANNEL_RAW                0
-#define HCI_CHANNEL_CONTROL    1
 #define HCI_CHANNEL_MONITOR    2
+#define HCI_CHANNEL_CONTROL    3
 
 struct hci_filter {
        unsigned long type_mask;
index daefaac511311348ac2772eeeed9d2f9ca0c7679..6822d2595aff983451b5c01b6286162635f25d9b 100644 (file)
@@ -427,7 +427,7 @@ enum {
 static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
 {
        struct hci_dev *hdev = conn->hdev;
-       return (test_bit(HCI_SSP_ENABLED, &hdev->flags) &&
+       return (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
                                test_bit(HCI_CONN_SSP_ENABLED, &conn->flags));
 }
 
@@ -907,11 +907,13 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status,
 
 static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
 {
-       u8 field_len;
-       size_t parsed;
+       size_t parsed = 0;
 
-       for (parsed = 0; parsed < data_len - 1; parsed += field_len) {
-               field_len = data[0];
+       if (data_len < 2)
+               return false;
+
+       while (parsed < data_len - 1) {
+               u8 field_len = data[0];
 
                if (field_len == 0)
                        break;
index ffc1377e092eb2a9b15b91a799e4e18672b10bb6..ebfd91fc20f804437241614418e7505ac15c83a0 100644 (file)
@@ -117,7 +117,7 @@ struct mgmt_mode {
 #define MGMT_OP_SET_DISCOVERABLE       0x0006
 struct mgmt_cp_set_discoverable {
        __u8    val;
-       __u16   timeout;
+       __le16  timeout;
 } __packed;
 #define MGMT_SET_DISCOVERABLE_SIZE     3
 
index 87d203ff7a8ad4d43ae97bcd91116529934b4ef7..9210bdc7bd8d417b94cf721b9ac671f7f2e700ed 100644 (file)
@@ -1327,7 +1327,7 @@ static inline struct ieee80211_rate *
 ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
                      const struct ieee80211_tx_info *c)
 {
-       if (WARN_ON(c->control.rates[0].idx < 0))
+       if (WARN_ON_ONCE(c->control.rates[0].idx < 0))
                return NULL;
        return &hw->wiphy->bands[c->band]->bitrates[c->control.rates[0].idx];
 }
index cf1a4a68ce444f03218ea0adbbd1f0ea178cc4d0..d1a758bc972afcb3f7c0103de781fa5720bea126 100644 (file)
@@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG
        help
          This option will show the mapping relationship between hardware irq
          numbers and Linux irq numbers. The mapping is exposed via debugfs
-         in the file "virq_mapping".
+         in the file "irq_domain_mapping".
 
          If you don't know what this means you don't need it.
 
index 3601f3fbf67c8808cb0223206713b1d1aeeb31bb..d34413e78628281f13d08bb8cd99cf7c544413fb 100644 (file)
@@ -23,7 +23,6 @@ static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
 static DEFINE_MUTEX(revmap_trees_mutex);
-static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_domain *irq_default_domain;
 
 /**
@@ -184,13 +183,16 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
 }
 
 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+                                        unsigned int max_irq,
                                         const struct irq_domain_ops *ops,
                                         void *host_data)
 {
        struct irq_domain *domain = irq_domain_alloc(of_node,
                                        IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
-       if (domain)
+       if (domain) {
+               domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0;
                irq_domain_add(domain);
+       }
        return domain;
 }
 
@@ -262,22 +264,6 @@ void irq_set_default_host(struct irq_domain *domain)
        irq_default_domain = domain;
 }
 
-/**
- * irq_set_virq_count() - Set the maximum number of linux irqs
- * @count: number of linux irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-void irq_set_virq_count(unsigned int count)
-{
-       pr_debug("irq: Trying to set virq count to %d\n", count);
-
-       BUG_ON(count < NUM_ISA_INTERRUPTS);
-       if (count < NR_IRQS)
-               irq_virq_count = count;
-}
-
 static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
                            irq_hw_number_t hwirq)
 {
@@ -320,13 +306,12 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
                pr_debug("irq: create_direct virq allocation failed\n");
                return 0;
        }
-       if (virq >= irq_virq_count) {
+       if (virq >= domain->revmap_data.nomap.max_irq) {
                pr_err("ERROR: no free irqs available below %i maximum\n",
-                       irq_virq_count);
+                       domain->revmap_data.nomap.max_irq);
                irq_free_desc(virq);
                return 0;
        }
-
        pr_debug("irq: create_direct obtained virq %d\n", virq);
 
        if (irq_setup_virq(domain, virq, virq)) {
@@ -350,7 +335,8 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
 unsigned int irq_create_mapping(struct irq_domain *domain,
                                irq_hw_number_t hwirq)
 {
-       unsigned int virq, hint;
+       unsigned int hint;
+       int virq;
 
        pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
 
@@ -377,13 +363,13 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
                return irq_domain_legacy_revmap(domain, hwirq);
 
        /* Allocate a virtual interrupt number */
-       hint = hwirq % irq_virq_count;
+       hint = hwirq % nr_irqs;
        if (hint == 0)
                hint++;
        virq = irq_alloc_desc_from(hint, 0);
-       if (!virq)
+       if (virq <= 0)
                virq = irq_alloc_desc_from(1, 0);
-       if (!virq) {
+       if (virq <= 0) {
                pr_debug("irq: -> virq allocation failed\n");
                return 0;
        }
@@ -515,7 +501,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
                              irq_hw_number_t hwirq)
 {
        unsigned int i;
-       unsigned int hint = hwirq % irq_virq_count;
+       unsigned int hint = hwirq % nr_irqs;
 
        /* Look for default domain if nececssary */
        if (domain == NULL)
@@ -536,7 +522,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
                if (data && (data->domain == domain) && (data->hwirq == hwirq))
                        return i;
                i++;
-               if (i >= irq_virq_count)
+               if (i >= nr_irqs)
                        i = 1;
        } while(i != hint);
        return 0;
@@ -642,8 +628,8 @@ static int virq_debug_show(struct seq_file *m, void *private)
        void *data;
        int i;
 
-       seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
-                     "chip name", "chip data", "domain name");
+       seq_printf(m, "%-5s  %-7s  %-15s  %-*s  %s\n", "irq", "hwirq",
+                     "chip name", 2 * sizeof(void *) + 2, "chip data", "domain name");
 
        for (i = 1; i < nr_irqs; i++) {
                desc = irq_to_desc(i);
@@ -666,7 +652,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
                        seq_printf(m, "%-15s  ", p);
 
                        data = irq_desc_get_chip_data(desc);
-                       seq_printf(m, "0x%16p  ", data);
+                       seq_printf(m, data ? "0x%p  " : "  %p  ", data);
 
                        if (desc->irq_data.domain && desc->irq_data.domain->of_node)
                                p = desc->irq_data.domain->of_node->full_name;
index e33af63a884a476e689af34a3a56003d2f485f2f..92a857e3786d173273986ba179f7e9bac1856af7 100644 (file)
@@ -665,6 +665,11 @@ int hci_dev_open(__u16 dev)
 
        hci_req_lock(hdev);
 
+       if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
+               ret = -ENODEV;
+               goto done;
+       }
+
        if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
                ret = -ERFKILL;
                goto done;
@@ -1849,6 +1854,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
 
        BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
 
+       set_bit(HCI_UNREGISTER, &hdev->dev_flags);
+
        write_lock(&hci_dev_list_lock);
        list_del(&hdev->list);
        write_unlock(&hci_dev_list_lock);
index b8e17e4dac8b4179d9ac82ad916baf28ed333662..94552b33d528447eea4b604b996c7d90ba0ab036 100644 (file)
@@ -1308,6 +1308,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
        if (chan->retry_count >= chan->remote_max_tx) {
                l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED);
                l2cap_chan_unlock(chan);
+               l2cap_chan_put(chan);
                return;
        }
 
@@ -1316,6 +1317,7 @@ static void l2cap_monitor_timeout(struct work_struct *work)
 
        l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
        l2cap_chan_unlock(chan);
+       l2cap_chan_put(chan);
 }
 
 static void l2cap_retrans_timeout(struct work_struct *work)
@@ -1335,6 +1337,7 @@ static void l2cap_retrans_timeout(struct work_struct *work)
        l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL);
 
        l2cap_chan_unlock(chan);
+       l2cap_chan_put(chan);
 }
 
 static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
index c4fe583b0af65f0a2bccfa9b3ee6e9d459f1c245..29122ed28ea96965433fb6086756244d9eabd508 100644 (file)
@@ -82,7 +82,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
        }
 
        if (la.l2_cid)
-               err = l2cap_add_scid(chan, la.l2_cid);
+               err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid));
        else
                err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
 
@@ -123,7 +123,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
        if (la.l2_cid && la.l2_psm)
                return -EINVAL;
 
-       err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr);
+       err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
+                               &la.l2_bdaddr);
        if (err)
                return err;
 
index 7fcff888713171cb760296726fdcfca19f72aaca..4ef275c69675ab116897da18663626a53ab6c6fe 100644 (file)
@@ -2523,13 +2523,18 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev,
 
        if (cp->val) {
                type = PAGE_SCAN_TYPE_INTERLACED;
-               acp.interval = 0x0024;  /* 22.5 msec page scan interval */
+
+               /* 22.5 msec page scan interval */
+               acp.interval = __constant_cpu_to_le16(0x0024);
        } else {
                type = PAGE_SCAN_TYPE_STANDARD; /* default */
-               acp.interval = 0x0800;  /* default 1.28 sec page scan */
+
+               /* default 1.28 sec page scan */
+               acp.interval = __constant_cpu_to_le16(0x0800);
        }
 
-       acp.window = 0x0012;    /* default 11.25 msec page scan window */
+       /* default 11.25 msec page scan window */
+       acp.window = __constant_cpu_to_le16(0x0012);
 
        err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, sizeof(acp),
                           &acp);
@@ -2936,7 +2941,7 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
                                          name, name_len);
 
        if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0)
-               eir_len = eir_append_data(&ev->eir[eir_len], eir_len,
+               eir_len = eir_append_data(ev->eir, eir_len,
                                          EIR_CLASS_OF_DEV, dev_class, 3);
 
        put_unaligned_le16(eir_len, &ev->eir_len);
index 702a1ae9220b79bd9e60cc25732201fe8750dcd2..27ca25ed70216979790ffd6c555baaf88bf4e7a4 100644 (file)
@@ -241,7 +241,6 @@ static void br_multicast_group_expired(unsigned long data)
        hlist_del_rcu(&mp->hlist[mdb->ver]);
        mdb->size--;
 
-       del_timer(&mp->query_timer);
        call_rcu_bh(&mp->rcu, br_multicast_free_group);
 
 out:
@@ -271,7 +270,6 @@ static void br_multicast_del_pg(struct net_bridge *br,
                rcu_assign_pointer(*pp, p->next);
                hlist_del_init(&p->mglist);
                del_timer(&p->timer);
-               del_timer(&p->query_timer);
                call_rcu_bh(&p->rcu, br_multicast_free_pg);
 
                if (!mp->ports && !mp->mglist &&
@@ -507,74 +505,6 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br,
        return NULL;
 }
 
-static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp)
-{
-       struct net_bridge *br = mp->br;
-       struct sk_buff *skb;
-
-       skb = br_multicast_alloc_query(br, &mp->addr);
-       if (!skb)
-               goto timer;
-
-       netif_rx(skb);
-
-timer:
-       if (++mp->queries_sent < br->multicast_last_member_count)
-               mod_timer(&mp->query_timer,
-                         jiffies + br->multicast_last_member_interval);
-}
-
-static void br_multicast_group_query_expired(unsigned long data)
-{
-       struct net_bridge_mdb_entry *mp = (void *)data;
-       struct net_bridge *br = mp->br;
-
-       spin_lock(&br->multicast_lock);
-       if (!netif_running(br->dev) || !mp->mglist ||
-           mp->queries_sent >= br->multicast_last_member_count)
-               goto out;
-
-       br_multicast_send_group_query(mp);
-
-out:
-       spin_unlock(&br->multicast_lock);
-}
-
-static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg)
-{
-       struct net_bridge_port *port = pg->port;
-       struct net_bridge *br = port->br;
-       struct sk_buff *skb;
-
-       skb = br_multicast_alloc_query(br, &pg->addr);
-       if (!skb)
-               goto timer;
-
-       br_deliver(port, skb);
-
-timer:
-       if (++pg->queries_sent < br->multicast_last_member_count)
-               mod_timer(&pg->query_timer,
-                         jiffies + br->multicast_last_member_interval);
-}
-
-static void br_multicast_port_group_query_expired(unsigned long data)
-{
-       struct net_bridge_port_group *pg = (void *)data;
-       struct net_bridge_port *port = pg->port;
-       struct net_bridge *br = port->br;
-
-       spin_lock(&br->multicast_lock);
-       if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
-           pg->queries_sent >= br->multicast_last_member_count)
-               goto out;
-
-       br_multicast_send_port_group_query(pg);
-
-out:
-       spin_unlock(&br->multicast_lock);
-}
-
 static struct net_bridge_mdb_entry *br_multicast_get_group(
        struct net_bridge *br, struct net_bridge_port *port,
        struct br_ip *group, int hash)
@@ -690,8 +620,6 @@ rehash:
        mp->addr = *group;
        setup_timer(&mp->timer, br_multicast_group_expired,
                    (unsigned long)mp);
-       setup_timer(&mp->query_timer, br_multicast_group_query_expired,
-                   (unsigned long)mp);
 
        hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]);
        mdb->size++;
@@ -746,8 +674,6 @@ static int br_multicast_add_group(struct net_bridge *br,
        hlist_add_head(&p->mglist, &port->mglist);
        setup_timer(&p->timer, br_multicast_port_group_expired,
                    (unsigned long)p);
-       setup_timer(&p->query_timer, br_multicast_port_group_query_expired,
-                   (unsigned long)p);
 
        rcu_assign_pointer(*pp, p);
 
@@ -1291,9 +1217,6 @@ static void br_multicast_leave_group(struct net_bridge *br,
                     time_after(mp->timer.expires, time) :
                     try_to_del_timer_sync(&mp->timer) >= 0)) {
                        mod_timer(&mp->timer, time);
-
-                       mp->queries_sent = 0;
-                       mod_timer(&mp->query_timer, now);
                }
 
                goto out;
@@ -1310,9 +1233,6 @@ static void br_multicast_leave_group(struct net_bridge *br,
                     time_after(p->timer.expires, time) :
                     try_to_del_timer_sync(&p->timer) >= 0)) {
                        mod_timer(&p->timer, time);
-
-                       p->queries_sent = 0;
-                       mod_timer(&p->query_timer, now);
                }
 
                break;
@@ -1681,7 +1601,6 @@ void br_multicast_stop(struct net_bridge *br)
                hlist_for_each_entry_safe(mp, p, n, &mdb->mhash[i],
                                          hlist[ver]) {
                        del_timer(&mp->timer);
-                       del_timer(&mp->query_timer);
                        call_rcu_bh(&mp->rcu, br_multicast_free_group);
                }
        }
index 0b67a63ad7a870e550c9d23d03ed7eb52ef854bf..e1d882257877374e21c7a314740a7ee7f76f4ccc 100644 (file)
@@ -82,9 +82,7 @@ struct net_bridge_port_group {
        struct hlist_node               mglist;
        struct rcu_head                 rcu;
        struct timer_list               timer;
-       struct timer_list               query_timer;
        struct br_ip                    addr;
-       u32                             queries_sent;
 };
 
 struct net_bridge_mdb_entry
@@ -94,10 +92,8 @@ struct net_bridge_mdb_entry
        struct net_bridge_port_group __rcu *ports;
        struct rcu_head                 rcu;
        struct timer_list               timer;
-       struct timer_list               query_timer;
        struct br_ip                    addr;
        bool                            mglist;
-       u32                             queries_sent;
 };
 
 struct net_bridge_mdb_htable
index baf8d281152cebc9e55ce8a7343d427b24b8b61e..e59840010d45c9bc25f521fe1ef0717d2de984af 100644 (file)
@@ -952,9 +952,11 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
                goto adjust_others;
        }
 
-       data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+       data = kmalloc(size + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
+                      gfp_mask);
        if (!data)
                goto nodata;
+       size = SKB_WITH_OVERHEAD(ksize(data));
 
        /* Copy only real data... and, alas, header. This should be
         * optimized for the cases when header is void.
index de9da21113a11be6c9f57b15a97b3936a574e512..cf73cc70ed2d2e1bfe1a5c837bc9993358e9904e 100644 (file)
@@ -74,16 +74,24 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
 
        iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
        if (iph == NULL)
-               return -NF_DROP;
+               return -NF_ACCEPT;
 
        /* Conntrack defragments packets, we might still see fragments
         * inside ICMP packets though. */
        if (iph->frag_off & htons(IP_OFFSET))
-               return -NF_DROP;
+               return -NF_ACCEPT;
 
        *dataoff = nhoff + (iph->ihl << 2);
        *protonum = iph->protocol;
 
+       /* Check bogus IP headers */
+       if (*dataoff > skb->len) {
+               pr_debug("nf_conntrack_ipv4: bogus IPv4 packet: "
+                        "nhoff %u, ihl %u, skblen %u\n",
+                        nhoff, iph->ihl << 2, skb->len);
+               return -NF_ACCEPT;
+       }
+
        return NF_ACCEPT;
 }
 
index 0cd36e33273bbb60102251047c4290a596ce77c1..8bb6adeb62c0eb7dcba14841a1f08375cfde6304 100644 (file)
@@ -701,11 +701,12 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
        skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
        if (skb) {
                if (sk_wmem_schedule(sk, skb->truesize)) {
+                       skb_reserve(skb, sk->sk_prot->max_header);
                        /*
                         * Make sure that we have exactly size bytes
                         * available to the caller, no more, no less.
                         */
-                       skb_reserve(skb, skb_tailroom(skb) - size);
+                       skb->avail_size = size;
                        return skb;
                }
                __kfree_skb(skb);
@@ -995,10 +996,9 @@ new_segment:
                                copy = seglen;
 
                        /* Where to copy to? */
-                       if (skb_tailroom(skb) > 0) {
+                       if (skb_availroom(skb) > 0) {
                                /* We have some space in skb head. Superb! */
-                               if (copy > skb_tailroom(skb))
-                                       copy = skb_tailroom(skb);
+                               copy = min_t(int, copy, skb_availroom(skb));
                                err = skb_add_data_nocache(sk, skb, from, copy);
                                if (err)
                                        goto do_fault;
@@ -3302,8 +3302,7 @@ void __init tcp_init(void)
 
        tcp_init_mem(&init_net);
        /* Set per-socket limits to no more than 1/128 the pressure threshold */
-       limit = nr_free_buffer_pages() << (PAGE_SHIFT - 10);
-       limit = max(limit, 128UL);
+       limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
        max_share = min(4UL*1024*1024, limit);
 
        sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
index 05b2dd56969127d7802a6a9817e4e738fea06578..9944c1d9a2180b8fab1b431b1a2792d7ccbc3b87 100644 (file)
@@ -474,8 +474,11 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
                if (!win_dep) {
                        m -= (new_sample >> 3);
                        new_sample += m;
-               } else if (m < new_sample)
-                       new_sample = m << 3;
+               } else {
+                       m <<= 3;
+                       if (m < new_sample)
+                               new_sample = m;
+               }
        } else {
                /* No previous measure. */
                new_sample = m << 3;
index 364784a91939c50eff90f8d8f29a174e1f63bafe..376b2cfbb685f78fb32d61823f0d4252729b6156 100644 (file)
@@ -2060,7 +2060,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
                /* Punt if not enough space exists in the first SKB for
                 * the data in the second
                 */
-               if (skb->len > skb_tailroom(to))
+               if (skb->len > skb_availroom(to))
                        break;
 
                if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp)))
index 94874b0bdcdcf9835fe0b0b53fd088c12db93305..9d4e155593190d81b99af8988899a0204a73ec80 100644 (file)
@@ -78,19 +78,6 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table);
 
    Hence the start of any table is given by get_table() below.  */
 
-/* Check for an extension */
-int
-ip6t_ext_hdr(u8 nexthdr)
-{
-       return  (nexthdr == IPPROTO_HOPOPTS)   ||
-               (nexthdr == IPPROTO_ROUTING)   ||
-               (nexthdr == IPPROTO_FRAGMENT)  ||
-               (nexthdr == IPPROTO_ESP)       ||
-               (nexthdr == IPPROTO_AH)        ||
-               (nexthdr == IPPROTO_NONE)      ||
-               (nexthdr == IPPROTO_DSTOPTS);
-}
-
 /* Returns whether matches rule or not. */
 /* Performance critical - called for every packet */
 static inline bool
@@ -2366,7 +2353,6 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
 EXPORT_SYMBOL(ip6t_register_table);
 EXPORT_SYMBOL(ip6t_unregister_table);
 EXPORT_SYMBOL(ip6t_do_table);
-EXPORT_SYMBOL(ip6t_ext_hdr);
 EXPORT_SYMBOL(ipv6_find_hdr);
 
 module_init(ip6_tables_init);
index 576fb25456dd7479a0ed51c50efad9c6a238c3d1..f76da5b3f5c5864f0b649187fca47517d244ce77 100644 (file)
@@ -3387,8 +3387,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                 */
                printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
                       sdata->name, ifmgd->bssid);
-               assoc_data->timeout = jiffies +
-                               TU_TO_EXP_TIME(req->bss->beacon_interval);
+               assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval);
        } else {
                assoc_data->have_beacon = true;
                assoc_data->sent_assoc = false;
index 3cc4487ac349997850940c6cbd274c196863f6aa..729f157a0efa690cf877dbd9dbb94dd1b09f1be6 100644 (file)
@@ -1592,7 +1592,7 @@ static int nf_conntrack_init_net(struct net *net)
        return 0;
 
 err_timeout:
-       nf_conntrack_timeout_fini(net);
+       nf_conntrack_ecache_fini(net);
 err_ecache:
        nf_conntrack_tstamp_fini(net);
 err_tstamp:
index 361eade62a09e58e06194fb78d8c6b07333f015a..0d07a1dcf60504758aace258dd0347f06f305797 100644 (file)
@@ -584,8 +584,8 @@ static bool tcp_in_window(const struct nf_conn *ct,
                         * Let's try to use the data from the packet.
                         */
                        sender->td_end = end;
-                       win <<= sender->td_scale;
-                       sender->td_maxwin = (win == 0 ? 1 : win);
+                       swin = win << sender->td_scale;
+                       sender->td_maxwin = (swin == 0 ? 1 : swin);
                        sender->td_maxend = end + sender->td_maxwin;
                        /*
                         * We haven't seen traffic in the other direction yet
index 7b76eb7192f37fc50167d39ff6d2a1d7ffc400e4..ef10ffcb4b6ffb5ed79eecdc8005dccc0de34575 100644 (file)
@@ -474,7 +474,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
 
        while (remaining_len > 0) {
 
-               frag_len = min_t(u16, local->remote_miu, remaining_len);
+               frag_len = min_t(size_t, local->remote_miu, remaining_len);
 
                pr_debug("Fragment %zd bytes remaining %zd",
                         frag_len, remaining_len);
@@ -497,7 +497,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
                release_sock(sk);
 
                remaining_len -= frag_len;
-               msg_ptr += len;
+               msg_ptr += frag_len;
        }
 
        kfree(msg_data);
index e49da27970227bda3885ba825e44f36ccf20df0e..f432c57af05d03addc5f856bfff8a784c19f19a1 100644 (file)
@@ -1294,6 +1294,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                        goto bad_res;
                }
 
+               if (!netif_running(netdev)) {
+                       result = -ENETDOWN;
+                       goto bad_res;
+               }
+
                nla_for_each_nested(nl_txq_params,
                                    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
                                    rem_txq_params) {
@@ -6384,7 +6389,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_get_key,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6416,7 +6421,7 @@ static struct genl_ops nl80211_ops[] = {
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .doit = nl80211_set_beacon,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6424,7 +6429,7 @@ static struct genl_ops nl80211_ops[] = {
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .doit = nl80211_start_ap,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6432,7 +6437,7 @@ static struct genl_ops nl80211_ops[] = {
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
                .doit = nl80211_stop_ap,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6448,7 +6453,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_set_station,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6464,7 +6469,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_del_station,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6497,7 +6502,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_del_mpath,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6505,7 +6510,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_set_bss,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6531,7 +6536,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_get_mesh_config,
                .policy = nl80211_policy,
                /* can be retrieved by unprivileged users */
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6664,7 +6669,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_setdel_pmksa,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6672,7 +6677,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_setdel_pmksa,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6680,7 +6685,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_flush_pmksa,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
@@ -6840,7 +6845,7 @@ static struct genl_ops nl80211_ops[] = {
                .doit = nl80211_probe_client,
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
-               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
        {
index 0af7f54e4f617f04c7dbab24e09a6b53fc4c9dd2..af648e08e61b7f279dd99b8e87797148d746dd2a 100644 (file)
@@ -780,8 +780,10 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
                if (cmd == SIOCSIWENCODEEXT) {
                        struct iw_encode_ext *ee = (void *) extra;
 
-                       if (iwp->length < sizeof(*ee) + ee->key_len)
-                               return -EFAULT;
+                       if (iwp->length < sizeof(*ee) + ee->key_len) {
+                               err = -EFAULT;
+                               goto out;
+                       }
                }
        }