summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '3.2.53/1028_linux-3.2.29.patch')
-rw-r--r--3.2.53/1028_linux-3.2.29.patch4279
1 files changed, 4279 insertions, 0 deletions
diff --git a/3.2.53/1028_linux-3.2.29.patch b/3.2.53/1028_linux-3.2.29.patch
new file mode 100644
index 0000000..3c65179
--- /dev/null
+++ b/3.2.53/1028_linux-3.2.29.patch
@@ -0,0 +1,4279 @@
+diff --git a/MAINTAINERS b/MAINTAINERS
+index f986e7d..82d7fa6 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -5452,7 +5452,7 @@ F: Documentation/blockdev/ramdisk.txt
+ F: drivers/block/brd.c
+
+ RANDOM NUMBER DRIVER
+-M: Matt Mackall <mpm@selenic.com>
++M: Theodore Ts'o" <tytso@mit.edu>
+ S: Maintained
+ F: drivers/char/random.c
+
+diff --git a/Makefile b/Makefile
+index 5368961..d96fc2a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 2
+-SUBLEVEL = 28
++SUBLEVEL = 29
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+
+diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
+index 640f909..6f1aca7 100644
+--- a/arch/alpha/include/asm/atomic.h
++++ b/arch/alpha/include/asm/atomic.h
+@@ -14,8 +14,8 @@
+ */
+
+
+-#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
+-#define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } )
++#define ATOMIC_INIT(i) { (i) }
++#define ATOMIC64_INIT(i) { (i) }
+
+ #define atomic_read(v) (*(volatile int *)&(v)->counter)
+ #define atomic64_read(v) (*(volatile long *)&(v)->counter)
+diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
+index 06edfef..3eeb47c 100644
+--- a/arch/alpha/include/asm/socket.h
++++ b/arch/alpha/include/asm/socket.h
+@@ -69,9 +69,11 @@
+
+ #define SO_RXQ_OVFL 40
+
++#ifdef __KERNEL__
+ /* O_NONBLOCK clashes with the bits used for socket types. Therefore we
+ * have to define SOCK_NONBLOCK to a different value here.
+ */
+ #define SOCK_NONBLOCK 0x40000000
++#endif /* __KERNEL__ */
+
+ #endif /* _ASM_SOCKET_H */
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index 9451dce..8512475 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -288,13 +288,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ *
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+- * <--------------- offset --------------------> <- type --> 0 0 0
++ * <--------------- offset ----------------------> < type -> 0 0 0
+ *
+- * This gives us up to 63 swap files and 32GB per swap file. Note that
++ * This gives us up to 31 swap files and 64GB per swap file. Note that
+ * the offset field is always non-zero.
+ */
+ #define __SWP_TYPE_SHIFT 3
+-#define __SWP_TYPE_BITS 6
++#define __SWP_TYPE_BITS 5
+ #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
+ #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
+
+diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
+index c202113..ea94765 100644
+--- a/arch/arm/mm/tlb-v7.S
++++ b/arch/arm/mm/tlb-v7.S
+@@ -38,10 +38,10 @@ ENTRY(v7wbi_flush_user_tlb_range)
+ dsb
+ mov r0, r0, lsr #PAGE_SHIFT @ align address
+ mov r1, r1, lsr #PAGE_SHIFT
+-#ifdef CONFIG_ARM_ERRATA_720789
+- mov r3, #0
+-#else
+ asid r3, r3 @ mask ASID
++#ifdef CONFIG_ARM_ERRATA_720789
++ ALT_SMP(W(mov) r3, #0 )
++ ALT_UP(W(nop) )
+ #endif
+ orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
+ mov r1, r1, lsl #PAGE_SHIFT
+diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
+index ad83dad..f0702f3 100644
+--- a/arch/arm/vfp/vfpmodule.c
++++ b/arch/arm/vfp/vfpmodule.c
+@@ -628,8 +628,10 @@ static int __init vfp_init(void)
+ if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
+ elf_hwcap |= HWCAP_NEON;
+ #endif
++#ifdef CONFIG_VFPv3
+ if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
+ elf_hwcap |= HWCAP_VFPv4;
++#endif
+ }
+ }
+ return 0;
+diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
+index f581a18..df7d12c 100644
+--- a/arch/x86/mm/hugetlbpage.c
++++ b/arch/x86/mm/hugetlbpage.c
+@@ -56,9 +56,16 @@ static int vma_shareable(struct vm_area_struct *vma, unsigned long addr)
+ }
+
+ /*
+- * search for a shareable pmd page for hugetlb.
++ * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc()
++ * and returns the corresponding pte. While this is not necessary for the
++ * !shared pmd case because we can allocate the pmd later as well, it makes the
++ * code much cleaner. pmd allocation is essential for the shared case because
++ * pud has to be populated inside the same i_mmap_mutex section - otherwise
++ * racing tasks could either miss the sharing (see huge_pte_offset) or select a
++ * bad pmd for sharing.
+ */
+-static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
++static pte_t *
++huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
+ {
+ struct vm_area_struct *vma = find_vma(mm, addr);
+ struct address_space *mapping = vma->vm_file->f_mapping;
+@@ -68,9 +75,10 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
+ struct vm_area_struct *svma;
+ unsigned long saddr;
+ pte_t *spte = NULL;
++ pte_t *pte;
+
+ if (!vma_shareable(vma, addr))
+- return;
++ return (pte_t *)pmd_alloc(mm, pud, addr);
+
+ mutex_lock(&mapping->i_mmap_mutex);
+ vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) {
+@@ -97,7 +105,9 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud)
+ put_page(virt_to_page(spte));
+ spin_unlock(&mm->page_table_lock);
+ out:
++ pte = (pte_t *)pmd_alloc(mm, pud, addr);
+ mutex_unlock(&mapping->i_mmap_mutex);
++ return pte;
+ }
+
+ /*
+@@ -142,8 +152,9 @@ pte_t *huge_pte_alloc(struct mm_struct *mm,
+ } else {
+ BUG_ON(sz != PMD_SIZE);
+ if (pud_none(*pud))
+- huge_pmd_share(mm, addr, pud);
+- pte = (pte_t *) pmd_alloc(mm, pud, addr);
++ pte = huge_pmd_share(mm, addr, pud);
++ else
++ pte = (pte_t *)pmd_alloc(mm, pud, addr);
+ }
+ }
+ BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
+diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
+index e7d13f5..d05f2fe 100644
+--- a/drivers/acpi/acpica/tbxface.c
++++ b/drivers/acpi/acpica/tbxface.c
+@@ -436,6 +436,7 @@ acpi_get_table_with_size(char *signature,
+
+ return (AE_NOT_FOUND);
+ }
++ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
+
+ acpi_status
+ acpi_get_table(char *signature,
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 8c78443..3790c80 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -385,7 +385,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
+ goto repeat;
+ }
+
+- dev->power.deferred_resume = false;
+ if (dev->power.no_callbacks)
+ goto no_callback; /* Assume success. */
+
+@@ -446,6 +445,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
+ wake_up_all(&dev->power.wait_queue);
+
+ if (dev->power.deferred_resume) {
++ dev->power.deferred_resume = false;
+ rpm_resume(dev, 0);
+ retval = -EAGAIN;
+ goto out;
+@@ -568,6 +568,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
+ || dev->parent->power.runtime_status == RPM_ACTIVE) {
+ atomic_inc(&dev->parent->power.child_count);
+ spin_unlock(&dev->parent->power.lock);
++ retval = 1;
+ goto no_callback; /* Assume success. */
+ }
+ spin_unlock(&dev->parent->power.lock);
+@@ -645,7 +646,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
+ }
+ wake_up_all(&dev->power.wait_queue);
+
+- if (!retval)
++ if (retval >= 0)
+ rpm_idle(dev, RPM_ASYNC);
+
+ out:
+diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
+index acda773..38aa6dd 100644
+--- a/drivers/block/cciss_scsi.c
++++ b/drivers/block/cciss_scsi.c
+@@ -763,16 +763,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout,
+ {
+ case CMD_TARGET_STATUS:
+ /* Pass it up to the upper layers... */
+- if( ei->ScsiStatus)
+- {
+-#if 0
+- printk(KERN_WARNING "cciss: cmd %p "
+- "has SCSI Status = %x\n",
+- c, ei->ScsiStatus);
+-#endif
+- cmd->result |= (ei->ScsiStatus << 1);
+- }
+- else { /* scsi status is zero??? How??? */
++ if (!ei->ScsiStatus) {
+
+ /* Ordinarily, this case should never happen, but there is a bug
+ in some released firmware revisions that allows it to happen
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index 650a308..de9c800 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -4,6 +4,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/hdreg.h>
+ #include <linux/module.h>
++#include <linux/mutex.h>
+ #include <linux/virtio.h>
+ #include <linux/virtio_blk.h>
+ #include <linux/scatterlist.h>
+@@ -26,14 +27,17 @@ struct virtio_blk
+ /* The disk structure for the kernel. */
+ struct gendisk *disk;
+
+- /* Request tracking. */
+- struct list_head reqs;
+-
+ mempool_t *pool;
+
+ /* Process context for config space updates */
+ struct work_struct config_work;
+
++ /* Lock for config space updates */
++ struct mutex config_lock;
++
++ /* enable config space updates */
++ bool config_enable;
++
+ /* What host tells us, plus 2 for header & tailer. */
+ unsigned int sg_elems;
+
+@@ -46,7 +50,6 @@ struct virtio_blk
+
+ struct virtblk_req
+ {
+- struct list_head list;
+ struct request *req;
+ struct virtio_blk_outhdr out_hdr;
+ struct virtio_scsi_inhdr in_hdr;
+@@ -90,7 +93,6 @@ static void blk_done(struct virtqueue *vq)
+ }
+
+ __blk_end_request_all(vbr->req, error);
+- list_del(&vbr->list);
+ mempool_free(vbr, vblk->pool);
+ }
+ /* In case queue is stopped waiting for more buffers. */
+@@ -175,7 +177,6 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
+ return false;
+ }
+
+- list_add_tail(&vbr->list, &vblk->reqs);
+ return true;
+ }
+
+@@ -316,6 +317,10 @@ static void virtblk_config_changed_work(struct work_struct *work)
+ char cap_str_2[10], cap_str_10[10];
+ u64 capacity, size;
+
++ mutex_lock(&vblk->config_lock);
++ if (!vblk->config_enable)
++ goto done;
++
+ /* Host must always specify the capacity. */
+ vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity),
+ &capacity, sizeof(capacity));
+@@ -338,6 +343,8 @@ static void virtblk_config_changed_work(struct work_struct *work)
+ cap_str_10, cap_str_2);
+
+ set_capacity(vblk->disk, capacity);
++done:
++ mutex_unlock(&vblk->config_lock);
+ }
+
+ static void virtblk_config_changed(struct virtio_device *vdev)
+@@ -381,11 +388,12 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
+ goto out_free_index;
+ }
+
+- INIT_LIST_HEAD(&vblk->reqs);
+ vblk->vdev = vdev;
+ vblk->sg_elems = sg_elems;
+ sg_init_table(vblk->sg, vblk->sg_elems);
++ mutex_init(&vblk->config_lock);
+ INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
++ vblk->config_enable = true;
+
+ /* We expect one virtqueue, for output. */
+ vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests");
+@@ -539,16 +547,19 @@ static void __devexit virtblk_remove(struct virtio_device *vdev)
+ struct virtio_blk *vblk = vdev->priv;
+ int index = vblk->index;
+
+- flush_work(&vblk->config_work);
++ /* Prevent config work handler from accessing the device. */
++ mutex_lock(&vblk->config_lock);
++ vblk->config_enable = false;
++ mutex_unlock(&vblk->config_lock);
+
+- /* Nothing should be pending. */
+- BUG_ON(!list_empty(&vblk->reqs));
++ del_gendisk(vblk->disk);
++ blk_cleanup_queue(vblk->disk->queue);
+
+ /* Stop all the virtqueues. */
+ vdev->config->reset(vdev);
+
+- del_gendisk(vblk->disk);
+- blk_cleanup_queue(vblk->disk->queue);
++ flush_work(&vblk->config_work);
++
+ put_disk(vblk->disk);
+ mempool_destroy(vblk->pool);
+ vdev->config->del_vqs(vdev);
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 631d4f6..8ae9235 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1114,6 +1114,16 @@ static void init_std_data(struct entropy_store *r)
+ mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL);
+ }
+
++/*
++ * Note that setup_arch() may call add_device_randomness()
++ * long before we get here. This allows seeding of the pools
++ * with some platform dependent data very early in the boot
++ * process. But it limits our options here. We must use
++ * statically allocated structures that already have all
++ * initializations complete at compile time. We should also
++ * take care not to overwrite the precious per platform data
++ * we were given.
++ */
+ static int rand_initialize(void)
+ {
+ init_std_data(&input_pool);
+@@ -1391,10 +1401,15 @@ static int proc_do_uuid(ctl_table *table, int write,
+ uuid = table->data;
+ if (!uuid) {
+ uuid = tmp_uuid;
+- uuid[8] = 0;
+- }
+- if (uuid[8] == 0)
+ generate_random_uuid(uuid);
++ } else {
++ static DEFINE_SPINLOCK(bootid_spinlock);
++
++ spin_lock(&bootid_spinlock);
++ if (!uuid[8])
++ generate_random_uuid(uuid);
++ spin_unlock(&bootid_spinlock);
++ }
+
+ sprintf(buf, "%pU", uuid);
+
+diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
+index 153980b..b298158 100644
+--- a/drivers/firmware/dmi_scan.c
++++ b/drivers/firmware/dmi_scan.c
+@@ -6,6 +6,7 @@
+ #include <linux/dmi.h>
+ #include <linux/efi.h>
+ #include <linux/bootmem.h>
++#include <linux/random.h>
+ #include <asm/dmi.h>
+
+ /*
+@@ -111,6 +112,8 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
+
+ dmi_table(buf, dmi_len, dmi_num, decode, NULL);
+
++ add_device_randomness(buf, dmi_len);
++
+ dmi_iounmap(buf, dmi_len);
+ return 0;
+ }
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index cc75c4b..3eed270 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -4748,17 +4748,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
+ continue;
+ }
+
+- if (intel_encoder->type == INTEL_OUTPUT_EDP) {
+- /* Use VBT settings if we have an eDP panel */
+- unsigned int edp_bpc = dev_priv->edp.bpp / 3;
+-
+- if (edp_bpc < display_bpc) {
+- DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
+- display_bpc = edp_bpc;
+- }
+- continue;
+- }
+-
+ /* Not one of the known troublemakers, check the EDID */
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ head) {
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index fae2050..c8ecaab 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -1152,10 +1152,14 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
+ WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
+
+ pp = ironlake_get_pp_control(dev_priv);
+- pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
++ /* We need to switch off panel power _and_ force vdd, for otherwise some
++ * panels get very unhappy and cease to work. */
++ pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+ I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
+
++ intel_dp->want_panel_vdd = false;
++
+ ironlake_wait_panel_off(intel_dp);
+ }
+
+@@ -1265,11 +1269,9 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
+ * ensure that we have vdd while we switch off the panel. */
+ ironlake_edp_panel_vdd_on(intel_dp);
+ ironlake_edp_backlight_off(intel_dp);
+- ironlake_edp_panel_off(intel_dp);
+-
+ intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
++ ironlake_edp_panel_off(intel_dp);
+ intel_dp_link_down(intel_dp);
+- ironlake_edp_panel_vdd_off(intel_dp, false);
+ }
+
+ static void intel_dp_commit(struct drm_encoder *encoder)
+@@ -1304,11 +1306,9 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
+ /* Switching the panel off requires vdd. */
+ ironlake_edp_panel_vdd_on(intel_dp);
+ ironlake_edp_backlight_off(intel_dp);
+- ironlake_edp_panel_off(intel_dp);
+-
+ intel_dp_sink_dpms(intel_dp, mode);
++ ironlake_edp_panel_off(intel_dp);
+ intel_dp_link_down(intel_dp);
+- ironlake_edp_panel_vdd_off(intel_dp, false);
+
+ if (is_cpu_edp(intel_dp))
+ ironlake_edp_pll_off(encoder);
+diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
+index cb006a7..3002d82 100644
+--- a/drivers/gpu/drm/nouveau/nvd0_display.c
++++ b/drivers/gpu/drm/nouveau/nvd0_display.c
+@@ -472,7 +472,7 @@ static int
+ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+ {
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+- const u32 data = (y << 16) | x;
++ const u32 data = (y << 16) | (x & 0xffff);
+
+ nv_wr32(crtc->dev, 0x64d084 + (nv_crtc->index * 0x1000), data);
+ nv_wr32(crtc->dev, 0x64d080 + (nv_crtc->index * 0x1000), 0x00000000);
+diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
+index 1b50ad8..4760466 100644
+--- a/drivers/gpu/drm/radeon/atombios.h
++++ b/drivers/gpu/drm/radeon/atombios.h
+@@ -101,6 +101,7 @@
+ #define ATOM_LCD_SELFTEST_START (ATOM_DISABLE+5)
+ #define ATOM_LCD_SELFTEST_STOP (ATOM_ENABLE+5)
+ #define ATOM_ENCODER_INIT (ATOM_DISABLE+7)
++#define ATOM_INIT (ATOM_DISABLE+7)
+ #define ATOM_GET_STATUS (ATOM_DISABLE+8)
+
+ #define ATOM_BLANKING 1
+@@ -251,25 +252,25 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
+ USHORT SetEngineClock; //Function Table,directly used by various SW components,latest version 1.1
+ USHORT SetMemoryClock; //Function Table,directly used by various SW components,latest version 1.1
+ USHORT SetPixelClock; //Function Table,directly used by various SW components,latest version 1.2
+- USHORT DynamicClockGating; //Atomic Table, indirectly used by various SW components,called from ASIC_Init
++ USHORT EnableDispPowerGating; //Atomic Table, indirectly used by various SW components,called from ASIC_Init
+ USHORT ResetMemoryDLL; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock
+ USHORT ResetMemoryDevice; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock
+- USHORT MemoryPLLInit;
+- USHORT AdjustDisplayPll; //only used by Bios
++ USHORT MemoryPLLInit; //Atomic Table, used only by Bios
++ USHORT AdjustDisplayPll; //Atomic Table, used by various SW componentes.
+ USHORT AdjustMemoryController; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock
+ USHORT EnableASIC_StaticPwrMgt; //Atomic Table, only used by Bios
+ USHORT ASIC_StaticPwrMgtStatusChange; //Obsolete , only used by Bios
+ USHORT DAC_LoadDetection; //Atomic Table, directly used by various SW components,latest version 1.2
+ USHORT LVTMAEncoderControl; //Atomic Table,directly used by various SW components,latest version 1.3
+- USHORT LCD1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1
++ USHORT HW_Misc_Operation; //Atomic Table, directly used by various SW components,latest version 1.1
+ USHORT DAC1EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1
+ USHORT DAC2EncoderControl; //Atomic Table, directly used by various SW components,latest version 1.1
+ USHORT DVOOutputControl; //Atomic Table, directly used by various SW components,latest version 1.1
+ USHORT CV1OutputControl; //Atomic Table, Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead
+- USHORT GetConditionalGoldenSetting; //only used by Bios
++ USHORT GetConditionalGoldenSetting; //Only used by Bios
+ USHORT TVEncoderControl; //Function Table,directly used by various SW components,latest version 1.1
+- USHORT TMDSAEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3
+- USHORT LVDSEncoderControl; //Atomic Table, directly used by various SW components,latest version 1.3
++ USHORT PatchMCSetting; //only used by BIOS
++ USHORT MC_SEQ_Control; //only used by BIOS
+ USHORT TV1OutputControl; //Atomic Table, Obsolete from Ry6xx, use DAC2 Output instead
+ USHORT EnableScaler; //Atomic Table, used only by Bios
+ USHORT BlankCRTC; //Atomic Table, directly used by various SW components,latest version 1.1
+@@ -282,7 +283,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
+ USHORT SetCRTC_Replication; //Atomic Table, used only by Bios
+ USHORT SelectCRTC_Source; //Atomic Table, directly used by various SW components,latest version 1.1
+ USHORT EnableGraphSurfaces; //Atomic Table, used only by Bios
+- USHORT UpdateCRTC_DoubleBufferRegisters;
++ USHORT UpdateCRTC_DoubleBufferRegisters; //Atomic Table, used only by Bios
+ USHORT LUT_AutoFill; //Atomic Table, only used by Bios
+ USHORT EnableHW_IconCursor; //Atomic Table, only used by Bios
+ USHORT GetMemoryClock; //Atomic Table, directly used by various SW components,latest version 1.1
+@@ -308,27 +309,36 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
+ USHORT SetVoltage; //Function Table,directly and/or indirectly used by various SW components,latest version 1.1
+ USHORT DAC1OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1
+ USHORT DAC2OutputControl; //Atomic Table, directly used by various SW components,latest version 1.1
+- USHORT SetupHWAssistedI2CStatus; //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C"
++ USHORT ComputeMemoryClockParam; //Function Table,only used by Bios, obsolete soon.Switch to use "ReadEDIDFromHWAssistedI2C"
+ USHORT ClockSource; //Atomic Table, indirectly used by various SW components,called from ASIC_Init
+ USHORT MemoryDeviceInit; //Atomic Table, indirectly used by various SW components,called from SetMemoryClock
+- USHORT EnableYUV; //Atomic Table, indirectly used by various SW components,called from EnableVGARender
++ USHORT GetDispObjectInfo; //Atomic Table, indirectly used by various SW components,called from EnableVGARender
+ USHORT DIG1EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1
+ USHORT DIG2EncoderControl; //Atomic Table,directly used by various SW components,latest version 1.1
+ USHORT DIG1TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1
+ USHORT DIG2TransmitterControl; //Atomic Table,directly used by various SW components,latest version 1.1
+ USHORT ProcessAuxChannelTransaction; //Function Table,only used by Bios
+ USHORT DPEncoderService; //Function Table,only used by Bios
++ USHORT GetVoltageInfo; //Function Table,only used by Bios since SI
+ }ATOM_MASTER_LIST_OF_COMMAND_TABLES;
+
+ // For backward compatible
+ #define ReadEDIDFromHWAssistedI2C ProcessI2cChannelTransaction
+-#define UNIPHYTransmitterControl DIG1TransmitterControl
+-#define LVTMATransmitterControl DIG2TransmitterControl
++#define DPTranslatorControl DIG2EncoderControl
++#define UNIPHYTransmitterControl DIG1TransmitterControl
++#define LVTMATransmitterControl DIG2TransmitterControl
+ #define SetCRTC_DPM_State GetConditionalGoldenSetting
+ #define SetUniphyInstance ASIC_StaticPwrMgtStatusChange
+ #define HPDInterruptService ReadHWAssistedI2CStatus
+ #define EnableVGA_Access GetSCLKOverMCLKRatio
+-#define GetDispObjectInfo EnableYUV
++#define EnableYUV GetDispObjectInfo
++#define DynamicClockGating EnableDispPowerGating
++#define SetupHWAssistedI2CStatus ComputeMemoryClockParam
++
++#define TMDSAEncoderControl PatchMCSetting
++#define LVDSEncoderControl MC_SEQ_Control
++#define LCD1OutputControl HW_Misc_Operation
++
+
+ typedef struct _ATOM_MASTER_COMMAND_TABLE
+ {
+@@ -495,6 +505,34 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5
+ // ucInputFlag
+ #define ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN 1 // 1-StrobeMode, 0-PerformanceMode
+
++// use for ComputeMemoryClockParamTable
++typedef struct _COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1
++{
++ union
++ {
++ ULONG ulClock;
++ ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output:UPPER_WORD=FB_DIV_INTEGER, LOWER_WORD=FB_DIV_FRAC shl (16-FB_FRACTION_BITS)
++ };
++ UCHAR ucDllSpeed; //Output
++ UCHAR ucPostDiv; //Output
++ union{
++ UCHAR ucInputFlag; //Input : ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN: 1-StrobeMode, 0-PerformanceMode
++ UCHAR ucPllCntlFlag; //Output:
++ };
++ UCHAR ucBWCntl;
++}COMPUTE_MEMORY_CLOCK_PARAM_PARAMETERS_V2_1;
++
++// definition of ucInputFlag
++#define MPLL_INPUT_FLAG_STROBE_MODE_EN 0x01
++// definition of ucPllCntlFlag
++#define MPLL_CNTL_FLAG_VCO_MODE_MASK 0x03
++#define MPLL_CNTL_FLAG_BYPASS_DQ_PLL 0x04
++#define MPLL_CNTL_FLAG_QDR_ENABLE 0x08
++#define MPLL_CNTL_FLAG_AD_HALF_RATE 0x10
++
++//MPLL_CNTL_FLAG_BYPASS_AD_PLL has a wrong name, should be BYPASS_DQ_PLL
++#define MPLL_CNTL_FLAG_BYPASS_AD_PLL 0x04
++
+ typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER
+ {
+ ATOM_COMPUTE_CLOCK_FREQ ulClock;
+@@ -562,6 +600,16 @@ typedef struct _DYNAMIC_CLOCK_GATING_PARAMETERS
+ #define DYNAMIC_CLOCK_GATING_PS_ALLOCATION DYNAMIC_CLOCK_GATING_PARAMETERS
+
+ /****************************************************************************/
++// Structure used by EnableDispPowerGatingTable.ctb
++/****************************************************************************/
++typedef struct _ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1
++{
++ UCHAR ucDispPipeId; // ATOM_CRTC1, ATOM_CRTC2, ...
++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE
++ UCHAR ucPadding[2];
++}ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1;
++
++/****************************************************************************/
+ // Structure used by EnableASIC_StaticPwrMgtTable.ctb
+ /****************************************************************************/
+ typedef struct _ENABLE_ASIC_STATIC_PWR_MGT_PARAMETERS
+@@ -807,6 +855,7 @@ typedef struct _ATOM_DIG_ENCODER_CONFIG_V4
+ #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ 0x00
+ #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ 0x01
+ #define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ 0x02
++#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_3_24GHZ 0x03
+ #define ATOM_ENCODER_CONFIG_V4_ENCODER_SEL 0x70
+ #define ATOM_ENCODER_CONFIG_V4_DIG0_ENCODER 0x00
+ #define ATOM_ENCODER_CONFIG_V4_DIG1_ENCODER 0x10
+@@ -814,6 +863,7 @@ typedef struct _ATOM_DIG_ENCODER_CONFIG_V4
+ #define ATOM_ENCODER_CONFIG_V4_DIG3_ENCODER 0x30
+ #define ATOM_ENCODER_CONFIG_V4_DIG4_ENCODER 0x40
+ #define ATOM_ENCODER_CONFIG_V4_DIG5_ENCODER 0x50
++#define ATOM_ENCODER_CONFIG_V4_DIG6_ENCODER 0x60
+
+ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V4
+ {
+@@ -1171,6 +1221,106 @@ typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V4
+ #define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER3 0x80 //EF
+
+
++typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V5
++{
++#if ATOM_BIG_ENDIAN
++ UCHAR ucReservd1:1;
++ UCHAR ucHPDSel:3;
++ UCHAR ucPhyClkSrcId:2;
++ UCHAR ucCoherentMode:1;
++ UCHAR ucReserved:1;
++#else
++ UCHAR ucReserved:1;
++ UCHAR ucCoherentMode:1;
++ UCHAR ucPhyClkSrcId:2;
++ UCHAR ucHPDSel:3;
++ UCHAR ucReservd1:1;
++#endif
++}ATOM_DIG_TRANSMITTER_CONFIG_V5;
++
++typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5
++{
++ USHORT usSymClock; // Encoder Clock in 10kHz,(DP mode)= linkclock/10, (TMDS/LVDS/HDMI)= pixel clock, (HDMI deep color), =pixel clock * deep_color_ratio
++ UCHAR ucPhyId; // 0=UNIPHYA, 1=UNIPHYB, 2=UNIPHYC, 3=UNIPHYD, 4= UNIPHYE 5=UNIPHYF
++ UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_xxx
++ UCHAR ucLaneNum; // indicate lane number 1-8
++ UCHAR ucConnObjId; // Connector Object Id defined in ObjectId.h
++ UCHAR ucDigMode; // indicate DIG mode
++ union{
++ ATOM_DIG_TRANSMITTER_CONFIG_V5 asConfig;
++ UCHAR ucConfig;
++ };
++ UCHAR ucDigEncoderSel; // indicate DIG front end encoder
++ UCHAR ucDPLaneSet;
++ UCHAR ucReserved;
++ UCHAR ucReserved1;
++}DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5;
++
++//ucPhyId
++#define ATOM_PHY_ID_UNIPHYA 0
++#define ATOM_PHY_ID_UNIPHYB 1
++#define ATOM_PHY_ID_UNIPHYC 2
++#define ATOM_PHY_ID_UNIPHYD 3
++#define ATOM_PHY_ID_UNIPHYE 4
++#define ATOM_PHY_ID_UNIPHYF 5
++#define ATOM_PHY_ID_UNIPHYG 6
++
++// ucDigEncoderSel
++#define ATOM_TRANMSITTER_V5__DIGA_SEL 0x01
++#define ATOM_TRANMSITTER_V5__DIGB_SEL 0x02
++#define ATOM_TRANMSITTER_V5__DIGC_SEL 0x04
++#define ATOM_TRANMSITTER_V5__DIGD_SEL 0x08
++#define ATOM_TRANMSITTER_V5__DIGE_SEL 0x10
++#define ATOM_TRANMSITTER_V5__DIGF_SEL 0x20
++#define ATOM_TRANMSITTER_V5__DIGG_SEL 0x40
++
++// ucDigMode
++#define ATOM_TRANSMITTER_DIGMODE_V5_DP 0
++#define ATOM_TRANSMITTER_DIGMODE_V5_LVDS 1
++#define ATOM_TRANSMITTER_DIGMODE_V5_DVI 2
++#define ATOM_TRANSMITTER_DIGMODE_V5_HDMI 3
++#define ATOM_TRANSMITTER_DIGMODE_V5_SDVO 4
++#define ATOM_TRANSMITTER_DIGMODE_V5_DP_MST 5
++
++// ucDPLaneSet
++#define DP_LANE_SET__0DB_0_4V 0x00
++#define DP_LANE_SET__0DB_0_6V 0x01
++#define DP_LANE_SET__0DB_0_8V 0x02
++#define DP_LANE_SET__0DB_1_2V 0x03
++#define DP_LANE_SET__3_5DB_0_4V 0x08
++#define DP_LANE_SET__3_5DB_0_6V 0x09
++#define DP_LANE_SET__3_5DB_0_8V 0x0a
++#define DP_LANE_SET__6DB_0_4V 0x10
++#define DP_LANE_SET__6DB_0_6V 0x11
++#define DP_LANE_SET__9_5DB_0_4V 0x18
++
++// ATOM_DIG_TRANSMITTER_CONFIG_V5 asConfig;
++// Bit1
++#define ATOM_TRANSMITTER_CONFIG_V5_COHERENT 0x02
++
++// Bit3:2
++#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SEL_MASK 0x0c
++#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SEL_SHIFT 0x02
++
++#define ATOM_TRANSMITTER_CONFIG_V5_P1PLL 0x00
++#define ATOM_TRANSMITTER_CONFIG_V5_P2PLL 0x04
++#define ATOM_TRANSMITTER_CONFIG_V5_P0PLL 0x08
++#define ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT 0x0c
++// Bit6:4
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD_SEL_MASK 0x70
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD_SEL_SHIFT 0x04
++
++#define ATOM_TRANSMITTER_CONFIG_V5_NO_HPD_SEL 0x00
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL 0x10
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL 0x20
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL 0x30
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL 0x40
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL 0x50
++#define ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL 0x60
++
++#define DIG_TRANSMITTER_CONTROL_PS_ALLOCATION_V1_5 DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5
++
++
+ /****************************************************************************/
+ // Structures used by ExternalEncoderControlTable V1.3
+ // ASIC Families: Evergreen, Llano, NI
+@@ -1793,6 +1943,7 @@ typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2
+ #define ATOM_PPLL_SS_TYPE_V3_P1PLL 0x00
+ #define ATOM_PPLL_SS_TYPE_V3_P2PLL 0x04
+ #define ATOM_PPLL_SS_TYPE_V3_DCPLL 0x08
++#define ATOM_PPLL_SS_TYPE_V3_P0PLL ATOM_PPLL_SS_TYPE_V3_DCPLL
+ #define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK 0x00FF
+ #define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT 0
+ #define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK 0x0F00
+@@ -2030,12 +2181,77 @@ typedef struct _SET_VOLTAGE_PARAMETERS_V2
+ USHORT usVoltageLevel; // real voltage level
+ }SET_VOLTAGE_PARAMETERS_V2;
+
++
++typedef struct _SET_VOLTAGE_PARAMETERS_V1_3
++{
++ UCHAR ucVoltageType; // To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI
++ UCHAR ucVoltageMode; // Indicate action: Set voltage level
++ USHORT usVoltageLevel; // real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. )
++}SET_VOLTAGE_PARAMETERS_V1_3;
++
++//ucVoltageType
++#define VOLTAGE_TYPE_VDDC 1
++#define VOLTAGE_TYPE_MVDDC 2
++#define VOLTAGE_TYPE_MVDDQ 3
++#define VOLTAGE_TYPE_VDDCI 4
++
++//SET_VOLTAGE_PARAMETERS_V3.ucVoltageMode
++#define ATOM_SET_VOLTAGE 0 //Set voltage Level
++#define ATOM_INIT_VOLTAGE_REGULATOR 3 //Init Regulator
++#define ATOM_SET_VOLTAGE_PHASE 4 //Set Vregulator Phase
++#define ATOM_GET_MAX_VOLTAGE 6 //Get Max Voltage, not used in SetVoltageTable v1.3
++#define ATOM_GET_VOLTAGE_LEVEL 6 //Get Voltage level from vitual voltage ID
++
++// define vitual voltage id in usVoltageLevel
++#define ATOM_VIRTUAL_VOLTAGE_ID0 0xff01
++#define ATOM_VIRTUAL_VOLTAGE_ID1 0xff02
++#define ATOM_VIRTUAL_VOLTAGE_ID2 0xff03
++#define ATOM_VIRTUAL_VOLTAGE_ID3 0xff04
++
+ typedef struct _SET_VOLTAGE_PS_ALLOCATION
+ {
+ SET_VOLTAGE_PARAMETERS sASICSetVoltage;
+ WRITE_ONE_BYTE_HW_I2C_DATA_PS_ALLOCATION sReserved;
+ }SET_VOLTAGE_PS_ALLOCATION;
+
++// New Added from SI for GetVoltageInfoTable, input parameter structure
++typedef struct _GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_1
++{
++ UCHAR ucVoltageType; // Input: To tell which voltage to set up, VDDC/MVDDC/MVDDQ/VDDCI
++ UCHAR ucVoltageMode; // Input: Indicate action: Get voltage info
++ USHORT usVoltageLevel; // Input: real voltage level in unit of mv or Voltage Phase (0, 1, 2, .. ) or Leakage Id
++ ULONG ulReserved;
++}GET_VOLTAGE_INFO_INPUT_PARAMETER_V1_1;
++
++// New Added from SI for GetVoltageInfoTable, output parameter structure when ucVotlageMode == ATOM_GET_VOLTAGE_VID
++typedef struct _GET_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1
++{
++ ULONG ulVotlageGpioState;
++ ULONG ulVoltageGPioMask;
++}GET_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1;
++
++// New Added from SI for GetVoltageInfoTable, output parameter structure when ucVotlageMode == ATOM_GET_VOLTAGE_STATEx_LEAKAGE_VID
++typedef struct _GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1
++{
++ USHORT usVoltageLevel;
++ USHORT usVoltageId; // Voltage Id programmed in Voltage Regulator
++ ULONG ulReseved;
++}GET_LEAKAGE_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_1;
++
++
++// GetVoltageInfo v1.1 ucVoltageMode
++#define ATOM_GET_VOLTAGE_VID 0x00
++#define ATOM_GET_VOTLAGE_INIT_SEQ 0x03
++#define ATOM_GET_VOLTTAGE_PHASE_PHASE_VID 0x04
++// for SI, this state map to 0xff02 voltage state in Power Play table, which is power boost state
++#define ATOM_GET_VOLTAGE_STATE0_LEAKAGE_VID 0x10
++
++// for SI, this state map to 0xff01 voltage state in Power Play table, which is performance state
++#define ATOM_GET_VOLTAGE_STATE1_LEAKAGE_VID 0x11
++// undefined power state
++#define ATOM_GET_VOLTAGE_STATE2_LEAKAGE_VID 0x12
++#define ATOM_GET_VOLTAGE_STATE3_LEAKAGE_VID 0x13
++
+ /****************************************************************************/
+ // Structures used by TVEncoderControlTable
+ /****************************************************************************/
+@@ -2065,9 +2281,9 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES
+ USHORT MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios
+ USHORT StandardVESA_Timing; // Only used by Bios
+ USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4
+- USHORT DAC_Info; // Will be obsolete from R600
++ USHORT PaletteData; // Only used by BIOS
+ USHORT LCD_Info; // Shared by various SW components,latest version 1.3, was called LVDS_Info
+- USHORT TMDS_Info; // Will be obsolete from R600
++ USHORT DIGTransmitterInfo; // Internal used by VBIOS only version 3.1
+ USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1
+ USHORT SupportedDevicesInfo; // Will be obsolete from R600
+ USHORT GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600
+@@ -2096,15 +2312,16 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES
+ USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1
+ }ATOM_MASTER_LIST_OF_DATA_TABLES;
+
+-// For backward compatible
+-#define LVDS_Info LCD_Info
+-
+ typedef struct _ATOM_MASTER_DATA_TABLE
+ {
+ ATOM_COMMON_TABLE_HEADER sHeader;
+ ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables;
+ }ATOM_MASTER_DATA_TABLE;
+
++// For backward compatible
++#define LVDS_Info LCD_Info
++#define DAC_Info PaletteData
++#define TMDS_Info DIGTransmitterInfo
+
+ /****************************************************************************/
+ // Structure used in MultimediaCapabilityInfoTable
+@@ -2171,7 +2388,9 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO
+ typedef struct _ATOM_FIRMWARE_CAPABILITY
+ {
+ #if ATOM_BIG_ENDIAN
+- USHORT Reserved:3;
++ USHORT Reserved:1;
++ USHORT SCL2Redefined:1;
++ USHORT PostWithoutModeSet:1;
+ USHORT HyperMemory_Size:4;
+ USHORT HyperMemory_Support:1;
+ USHORT PPMode_Assigned:1;
+@@ -2193,7 +2412,9 @@ typedef struct _ATOM_FIRMWARE_CAPABILITY
+ USHORT PPMode_Assigned:1;
+ USHORT HyperMemory_Support:1;
+ USHORT HyperMemory_Size:4;
+- USHORT Reserved:3;
++ USHORT PostWithoutModeSet:1;
++ USHORT SCL2Redefined:1;
++ USHORT Reserved:1;
+ #endif
+ }ATOM_FIRMWARE_CAPABILITY;
+
+@@ -2418,7 +2639,8 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_2
+ USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit
+ ULONG ulReserved4; //Was ulAsicMaximumVoltage
+ ULONG ulMinPixelClockPLL_Output; //In 10Khz unit
+- ULONG ulReserved5; //Was usMinEngineClockPLL_Input and usMaxEngineClockPLL_Input
++ UCHAR ucRemoteDisplayConfig;
++ UCHAR ucReserved5[3]; //Was usMinEngineClockPLL_Input and usMaxEngineClockPLL_Input
+ ULONG ulReserved6; //Was usMinEngineClockPLL_Output and usMinMemoryClockPLL_Input
+ ULONG ulReserved7; //Was usMaxMemoryClockPLL_Input and usMinMemoryClockPLL_Output
+ USHORT usReserved11; //Was usMaxPixelClock; //In 10Khz unit, Max. Pclk used only for DAC
+@@ -2438,6 +2660,11 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_2
+
+ #define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_2
+
++
++// definition of ucRemoteDisplayConfig
++#define REMOTE_DISPLAY_DISABLE 0x00
++#define REMOTE_DISPLAY_ENABLE 0x01
++
+ /****************************************************************************/
+ // Structures used in IntegratedSystemInfoTable
+ /****************************************************************************/
+@@ -2660,8 +2887,9 @@ usMinDownStreamHTLinkWidth: same as above.
+ #define INTEGRATED_SYSTEM_INFO__AMD_CPU__GREYHOUND 2
+ #define INTEGRATED_SYSTEM_INFO__AMD_CPU__K8 3
+ #define INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH 4
++#define INTEGRATED_SYSTEM_INFO__AMD_CPU__OROCHI 5
+
+-#define INTEGRATED_SYSTEM_INFO__AMD_CPU__MAX_CODE INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH // this deff reflects max defined CPU code
++#define INTEGRATED_SYSTEM_INFO__AMD_CPU__MAX_CODE INTEGRATED_SYSTEM_INFO__AMD_CPU__OROCHI // this deff reflects max defined CPU code
+
+ #define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001
+ #define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002
+@@ -2753,6 +2981,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V5
+ #define ASIC_INT_DIG4_ENCODER_ID 0x0b
+ #define ASIC_INT_DIG5_ENCODER_ID 0x0c
+ #define ASIC_INT_DIG6_ENCODER_ID 0x0d
++#define ASIC_INT_DIG7_ENCODER_ID 0x0e
+
+ //define Encoder attribute
+ #define ATOM_ANALOG_ENCODER 0
+@@ -3226,15 +3455,23 @@ typedef struct _ATOM_LCD_INFO_V13
+
+ UCHAR ucPowerSequenceDIGONtoDE_in4Ms;
+ UCHAR ucPowerSequenceDEtoVARY_BL_in4Ms;
+- UCHAR ucPowerSequenceDEtoDIGON_in4Ms;
+ UCHAR ucPowerSequenceVARY_BLtoDE_in4Ms;
++ UCHAR ucPowerSequenceDEtoDIGON_in4Ms;
+
+ UCHAR ucOffDelay_in4Ms;
+ UCHAR ucPowerSequenceVARY_BLtoBLON_in4Ms;
+ UCHAR ucPowerSequenceBLONtoVARY_BL_in4Ms;
+ UCHAR ucReserved1;
+
+- ULONG ulReserved[4];
++ UCHAR ucDPCD_eDP_CONFIGURATION_CAP; // dpcd 0dh
++ UCHAR ucDPCD_MAX_LINK_RATE; // dpcd 01h
++ UCHAR ucDPCD_MAX_LANE_COUNT; // dpcd 02h
++ UCHAR ucDPCD_MAX_DOWNSPREAD; // dpcd 03h
++
++ USHORT usMaxPclkFreqInSingleLink; // Max PixelClock frequency in single link mode.
++ UCHAR uceDPToLVDSRxId;
++ UCHAR ucLcdReservd;
++ ULONG ulReserved[2];
+ }ATOM_LCD_INFO_V13;
+
+ #define ATOM_LCD_INFO_LAST ATOM_LCD_INFO_V13
+@@ -3273,6 +3510,11 @@ typedef struct _ATOM_LCD_INFO_V13
+ //Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP.
+ #define LCDPANEL_CAP_V13_eDP 0x4 // = LCDPANEL_CAP_eDP no change comparing to previous version
+
++//uceDPToLVDSRxId
++#define eDP_TO_LVDS_RX_DISABLE 0x00 // no eDP->LVDS translator chip
++#define eDP_TO_LVDS_COMMON_ID 0x01 // common eDP->LVDS translator chip without AMD SW init
++#define eDP_TO_LVDS_RT_ID 0x02 // RT tanslator which require AMD SW init
++
+ typedef struct _ATOM_PATCH_RECORD_MODE
+ {
+ UCHAR ucRecordType;
+@@ -3317,6 +3559,7 @@ typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD
+ #define LCD_CAP_RECORD_TYPE 3
+ #define LCD_FAKE_EDID_PATCH_RECORD_TYPE 4
+ #define LCD_PANEL_RESOLUTION_RECORD_TYPE 5
++#define LCD_EDID_OFFSET_PATCH_RECORD_TYPE 6
+ #define ATOM_RECORD_END_TYPE 0xFF
+
+ /****************************Spread Spectrum Info Table Definitions **********************/
+@@ -3528,6 +3771,7 @@ else //Non VGA case
+
+ CAIL needs to claim an reserved area defined by FBAccessAreaOffset and usFBUsedbyDrvInKB in non VGA case.*/
+
++/***********************************************************************************/
+ #define ATOM_MAX_FIRMWARE_VRAM_USAGE_INFO 1
+
+ typedef struct _ATOM_FIRMWARE_VRAM_RESERVE_INFO
+@@ -3818,13 +4062,17 @@ typedef struct _EXT_DISPLAY_PATH
+ ATOM_DP_CONN_CHANNEL_MAPPING asDPMapping;
+ ATOM_DVI_CONN_CHANNEL_MAPPING asDVIMapping;
+ };
+- UCHAR ucReserved;
+- USHORT usReserved[2];
++ UCHAR ucChPNInvert; // bit vector for up to 8 lanes, =0: P and N is not invert, =1 P and N is inverted
++ USHORT usCaps;
++ USHORT usReserved;
+ }EXT_DISPLAY_PATH;
+
+ #define NUMBER_OF_UCHAR_FOR_GUID 16
+ #define MAX_NUMBER_OF_EXT_DISPLAY_PATH 7
+
++//usCaps
++#define EXT_DISPLAY_PATH_CAPS__HBR2_DISABLE 0x01
++
+ typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO
+ {
+ ATOM_COMMON_TABLE_HEADER sHeader;
+@@ -3832,7 +4080,9 @@ typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO
+ EXT_DISPLAY_PATH sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries.
+ UCHAR ucChecksum; // a simple Checksum of the sum of whole structure equal to 0x0.
+ UCHAR uc3DStereoPinId; // use for eDP panel
+- UCHAR Reserved [6]; // for potential expansion
++ UCHAR ucRemoteDisplayConfig;
++ UCHAR uceDPToLVDSRxId;
++ UCHAR Reserved[4]; // for potential expansion
+ }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO;
+
+ //Related definitions, all records are different but they have a commond header
+@@ -3977,6 +4227,7 @@ typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD
+ #define GPIO_PIN_STATE_ACTIVE_HIGH 0x1
+
+ // Indexes to GPIO array in GLSync record
++// GLSync record is for Frame Lock/Gen Lock feature.
+ #define ATOM_GPIO_INDEX_GLSYNC_REFCLK 0
+ #define ATOM_GPIO_INDEX_GLSYNC_HSYNC 1
+ #define ATOM_GPIO_INDEX_GLSYNC_VSYNC 2
+@@ -3984,7 +4235,9 @@ typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD
+ #define ATOM_GPIO_INDEX_GLSYNC_SWAP_GNT 4
+ #define ATOM_GPIO_INDEX_GLSYNC_INTERRUPT 5
+ #define ATOM_GPIO_INDEX_GLSYNC_V_RESET 6
+-#define ATOM_GPIO_INDEX_GLSYNC_MAX 7
++#define ATOM_GPIO_INDEX_GLSYNC_SWAP_CNTL 7
++#define ATOM_GPIO_INDEX_GLSYNC_SWAP_SEL 8
++#define ATOM_GPIO_INDEX_GLSYNC_MAX 9
+
+ typedef struct _ATOM_ENCODER_DVO_CF_RECORD
+ {
+@@ -3994,7 +4247,8 @@ typedef struct _ATOM_ENCODER_DVO_CF_RECORD
+ }ATOM_ENCODER_DVO_CF_RECORD;
+
+ // Bit maps for ATOM_ENCODER_CAP_RECORD.ucEncoderCap
+-#define ATOM_ENCODER_CAP_RECORD_HBR2 0x01 // DP1.2 HBR2 is supported by this path
++#define ATOM_ENCODER_CAP_RECORD_HBR2 0x01 // DP1.2 HBR2 is supported by HW encoder
++#define ATOM_ENCODER_CAP_RECORD_HBR2_EN 0x02 // DP1.2 HBR2 setting is qualified and HBR2 can be enabled
+
+ typedef struct _ATOM_ENCODER_CAP_RECORD
+ {
+@@ -4003,11 +4257,13 @@ typedef struct _ATOM_ENCODER_CAP_RECORD
+ USHORT usEncoderCap;
+ struct {
+ #if ATOM_BIG_ENDIAN
+- USHORT usReserved:15; // Bit1-15 may be defined for other capability in future
++ USHORT usReserved:14; // Bit1-15 may be defined for other capability in future
++ USHORT usHBR2En:1; // Bit1 is for DP1.2 HBR2 enable
+ USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability.
+ #else
+ USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability.
+- USHORT usReserved:15; // Bit1-15 may be defined for other capability in future
++ USHORT usHBR2En:1; // Bit1 is for DP1.2 HBR2 enable
++ USHORT usReserved:14; // Bit1-15 may be defined for other capability in future
+ #endif
+ };
+ };
+@@ -4157,6 +4413,7 @@ typedef struct _ATOM_VOLTAGE_CONTROL
+ #define VOLTAGE_CONTROL_ID_VT1556M 0x07
+ #define VOLTAGE_CONTROL_ID_CHL822x 0x08
+ #define VOLTAGE_CONTROL_ID_VT1586M 0x09
++#define VOLTAGE_CONTROL_ID_UP1637 0x0A
+
+ typedef struct _ATOM_VOLTAGE_OBJECT
+ {
+@@ -4193,6 +4450,69 @@ typedef struct _ATOM_LEAKID_VOLTAGE
+ USHORT usVoltage;
+ }ATOM_LEAKID_VOLTAGE;
+
++typedef struct _ATOM_VOLTAGE_OBJECT_HEADER_V3{
++ UCHAR ucVoltageType; //Indicate Voltage Source: VDDC, MVDDC, MVDDQ or MVDDCI
++ UCHAR ucVoltageMode; //Indicate voltage control mode: Init/Set/Leakage/Set phase
++ USHORT usSize; //Size of Object
++}ATOM_VOLTAGE_OBJECT_HEADER_V3;
++
++typedef struct _VOLTAGE_LUT_ENTRY_V2
++{
++ ULONG ulVoltageId; // The Voltage ID which is used to program GPIO register
++ USHORT usVoltageValue; // The corresponding Voltage Value, in mV
++}VOLTAGE_LUT_ENTRY_V2;
++
++typedef struct _LEAKAGE_VOLTAGE_LUT_ENTRY_V2
++{
++ USHORT usVoltageLevel; // The Voltage ID which is used to program GPIO register
++ USHORT usVoltageId;
++ USHORT usLeakageId; // The corresponding Voltage Value, in mV
++}LEAKAGE_VOLTAGE_LUT_ENTRY_V2;
++
++typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3
++{
++ ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;
++ UCHAR ucVoltageRegulatorId; //Indicate Voltage Regulator Id
++ UCHAR ucVoltageControlI2cLine;
++ UCHAR ucVoltageControlAddress;
++ UCHAR ucVoltageControlOffset;
++ ULONG ulReserved;
++ VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff
++}ATOM_I2C_VOLTAGE_OBJECT_V3;
++
++typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3
++{
++ ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;
++ UCHAR ucVoltageGpioCntlId; // default is 0 which indicate control through CG VID mode
++ UCHAR ucGpioEntryNum; // indiate the entry numbers of Votlage/Gpio value Look up table
++ UCHAR ucPhaseDelay; // phase delay in unit of micro second
++ UCHAR ucReserved;
++ ULONG ulGpioMaskVal; // GPIO Mask value
++ VOLTAGE_LUT_ENTRY_V2 asVolGpioLut[1];
++}ATOM_GPIO_VOLTAGE_OBJECT_V3;
++
++typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
++{
++ ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;
++ UCHAR ucLeakageCntlId; // default is 0
++ UCHAR ucLeakageEntryNum; // indicate the entry number of LeakageId/Voltage Lut table
++ UCHAR ucReserved[2];
++ ULONG ulMaxVoltageLevel;
++ LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[1];
++}ATOM_LEAKAGE_VOLTAGE_OBJECT_V3;
++
++typedef union _ATOM_VOLTAGE_OBJECT_V3{
++ ATOM_GPIO_VOLTAGE_OBJECT_V3 asGpioVoltageObj;
++ ATOM_I2C_VOLTAGE_OBJECT_V3 asI2cVoltageObj;
++ ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 asLeakageObj;
++}ATOM_VOLTAGE_OBJECT_V3;
++
++typedef struct _ATOM_VOLTAGE_OBJECT_INFO_V3_1
++{
++ ATOM_COMMON_TABLE_HEADER sHeader;
++ ATOM_VOLTAGE_OBJECT_V3 asVoltageObj[3]; //Info for Voltage control
++}ATOM_VOLTAGE_OBJECT_INFO_V3_1;
++
+ typedef struct _ATOM_ASIC_PROFILE_VOLTAGE
+ {
+ UCHAR ucProfileId;
+@@ -4305,7 +4625,18 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6
+ USHORT usHDMISSpreadRateIn10Hz;
+ USHORT usDVISSPercentage;
+ USHORT usDVISSpreadRateIn10Hz;
+- ULONG ulReserved3[21];
++ ULONG SclkDpmBoostMargin;
++ ULONG SclkDpmThrottleMargin;
++ USHORT SclkDpmTdpLimitPG;
++ USHORT SclkDpmTdpLimitBoost;
++ ULONG ulBoostEngineCLock;
++ UCHAR ulBoostVid_2bit;
++ UCHAR EnableBoost;
++ USHORT GnbTdpLimit;
++ USHORT usMaxLVDSPclkFreqInSingleLink;
++ UCHAR ucLvdsMisc;
++ UCHAR ucLVDSReserved;
++ ULONG ulReserved3[15];
+ ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo;
+ }ATOM_INTEGRATED_SYSTEM_INFO_V6;
+
+@@ -4313,9 +4644,16 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6
+ #define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01
+ #define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__DISABLE_AUX_HW_MODE_DETECTION 0x08
+
+-// ulOtherDisplayMisc
+-#define INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT 0x01
++//ucLVDSMisc:
++#define SYS_INFO_LVDSMISC__888_FPDI_MODE 0x01
++#define SYS_INFO_LVDSMISC__DL_CH_SWAP 0x02
++#define SYS_INFO_LVDSMISC__888_BPC 0x04
++#define SYS_INFO_LVDSMISC__OVERRIDE_EN 0x08
++#define SYS_INFO_LVDSMISC__BLON_ACTIVE_LOW 0x10
+
++// not used any more
++#define SYS_INFO_LVDSMISC__VSYNC_ACTIVE_LOW 0x04
++#define SYS_INFO_LVDSMISC__HSYNC_ACTIVE_LOW 0x08
+
+ /**********************************************************************************************************************
+ ATOM_INTEGRATED_SYSTEM_INFO_V6 Description
+@@ -4384,7 +4722,208 @@ ucUMAChannelNumber: System memory channel numbers.
+ ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default
+ ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback.
+ ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications.
+-sAvail_SCLK[5]: Arrays to provide available list of SLCK and corresponding voltage, order from low to high
++sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high
++ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns.
++ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz.
++ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz.
++ulDDR_DLL_PowerUpTime: DDR PHY DLL power up time. Unit in ns.
++ulDDR_PLL_PowerUpTime: DDR PHY PLL power up time. Unit in ns.
++usPCIEClkSSPercentage: PCIE Clock Spred Spectrum Percentage in unit 0.01%; 100 mean 1%.
++usPCIEClkSSType: PCIE Clock Spred Spectrum Type. 0 for Down spread(default); 1 for Center spread.
++usLvdsSSPercentage: LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting.
++usLvdsSSpreadRateIn10Hz: LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting.
++usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting.
++usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting.
++usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting.
++usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting.
++usMaxLVDSPclkFreqInSingleLink: Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz
++ucLVDSMisc: [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode
++ [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped
++ [bit2] LVDS 888bit per color mode =0: 666 bit per color =1:888 bit per color
++ [bit3] LVDS parameter override enable =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used
++ [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low )
++**********************************************************************************************************************/
++
++// this Table is used for Liano/Ontario APU
++typedef struct _ATOM_FUSION_SYSTEM_INFO_V1
++{
++ ATOM_INTEGRATED_SYSTEM_INFO_V6 sIntegratedSysInfo;
++ ULONG ulPowerplayTable[128];
++}ATOM_FUSION_SYSTEM_INFO_V1;
++/**********************************************************************************************************************
++ ATOM_FUSION_SYSTEM_INFO_V1 Description
++sIntegratedSysInfo: refer to ATOM_INTEGRATED_SYSTEM_INFO_V6 definition.
++ulPowerplayTable[128]: This 512 bytes memory is used to save ATOM_PPLIB_POWERPLAYTABLE3, starting form ulPowerplayTable[0]
++**********************************************************************************************************************/
++
++// this IntegrateSystemInfoTable is used for Trinity APU
++typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7
++{
++ ATOM_COMMON_TABLE_HEADER sHeader;
++ ULONG ulBootUpEngineClock;
++ ULONG ulDentistVCOFreq;
++ ULONG ulBootUpUMAClock;
++ ATOM_CLK_VOLT_CAPABILITY sDISPCLK_Voltage[4];
++ ULONG ulBootUpReqDisplayVector;
++ ULONG ulOtherDisplayMisc;
++ ULONG ulGPUCapInfo;
++ ULONG ulSB_MMIO_Base_Addr;
++ USHORT usRequestedPWMFreqInHz;
++ UCHAR ucHtcTmpLmt;
++ UCHAR ucHtcHystLmt;
++ ULONG ulMinEngineClock;
++ ULONG ulSystemConfig;
++ ULONG ulCPUCapInfo;
++ USHORT usNBP0Voltage;
++ USHORT usNBP1Voltage;
++ USHORT usBootUpNBVoltage;
++ USHORT usExtDispConnInfoOffset;
++ USHORT usPanelRefreshRateRange;
++ UCHAR ucMemoryType;
++ UCHAR ucUMAChannelNumber;
++ UCHAR strVBIOSMsg[40];
++ ULONG ulReserved[20];
++ ATOM_AVAILABLE_SCLK_LIST sAvail_SCLK[5];
++ ULONG ulGMCRestoreResetTime;
++ ULONG ulMinimumNClk;
++ ULONG ulIdleNClk;
++ ULONG ulDDR_DLL_PowerUpTime;
++ ULONG ulDDR_PLL_PowerUpTime;
++ USHORT usPCIEClkSSPercentage;
++ USHORT usPCIEClkSSType;
++ USHORT usLvdsSSPercentage;
++ USHORT usLvdsSSpreadRateIn10Hz;
++ USHORT usHDMISSPercentage;
++ USHORT usHDMISSpreadRateIn10Hz;
++ USHORT usDVISSPercentage;
++ USHORT usDVISSpreadRateIn10Hz;
++ ULONG SclkDpmBoostMargin;
++ ULONG SclkDpmThrottleMargin;
++ USHORT SclkDpmTdpLimitPG;
++ USHORT SclkDpmTdpLimitBoost;
++ ULONG ulBoostEngineCLock;
++ UCHAR ulBoostVid_2bit;
++ UCHAR EnableBoost;
++ USHORT GnbTdpLimit;
++ USHORT usMaxLVDSPclkFreqInSingleLink;
++ UCHAR ucLvdsMisc;
++ UCHAR ucLVDSReserved;
++ UCHAR ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
++ UCHAR ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
++ UCHAR ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
++ UCHAR ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
++ UCHAR ucLVDSOffToOnDelay_in4Ms;
++ UCHAR ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
++ UCHAR ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
++ UCHAR ucLVDSReserved1;
++ ULONG ulLCDBitDepthControlVal;
++ ULONG ulNbpStateMemclkFreq[4];
++ USHORT usNBP2Voltage;
++ USHORT usNBP3Voltage;
++ ULONG ulNbpStateNClkFreq[4];
++ UCHAR ucNBDPMEnable;
++ UCHAR ucReserved[3];
++ UCHAR ucDPMState0VclkFid;
++ UCHAR ucDPMState0DclkFid;
++ UCHAR ucDPMState1VclkFid;
++ UCHAR ucDPMState1DclkFid;
++ UCHAR ucDPMState2VclkFid;
++ UCHAR ucDPMState2DclkFid;
++ UCHAR ucDPMState3VclkFid;
++ UCHAR ucDPMState3DclkFid;
++ ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo;
++}ATOM_INTEGRATED_SYSTEM_INFO_V1_7;
++
++// ulOtherDisplayMisc
++#define INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT 0x01
++#define INTEGRATED_SYSTEM_INFO__GET_BOOTUP_DISPLAY_CALLBACK_FUNC_SUPPORT 0x02
++#define INTEGRATED_SYSTEM_INFO__GET_EXPANSION_CALLBACK_FUNC_SUPPORT 0x04
++#define INTEGRATED_SYSTEM_INFO__FAST_BOOT_SUPPORT 0x08
++
++// ulGPUCapInfo
++#define SYS_INFO_GPUCAPS__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01
++#define SYS_INFO_GPUCAPS__DP_SINGLEPLL_MODE 0x02
++#define SYS_INFO_GPUCAPS__DISABLE_AUX_MODE_DETECT 0x08
++
++/**********************************************************************************************************************
++ ATOM_INTEGRATED_SYSTEM_INFO_V1_7 Description
++ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock
++ulDentistVCOFreq: Dentist VCO clock in 10kHz unit.
++ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit.
++sDISPCLK_Voltage: Report Display clock voltage requirement.
++
++ulBootUpReqDisplayVector: VBIOS boot up display IDs, following are supported devices in Trinity projects:
++ ATOM_DEVICE_CRT1_SUPPORT 0x0001
++ ATOM_DEVICE_DFP1_SUPPORT 0x0008
++ ATOM_DEVICE_DFP6_SUPPORT 0x0040
++ ATOM_DEVICE_DFP2_SUPPORT 0x0080
++ ATOM_DEVICE_DFP3_SUPPORT 0x0200
++ ATOM_DEVICE_DFP4_SUPPORT 0x0400
++ ATOM_DEVICE_DFP5_SUPPORT 0x0800
++ ATOM_DEVICE_LCD1_SUPPORT 0x0002
++ulOtherDisplayMisc: bit[0]=0: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is not supported by SBIOS.
++ =1: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is supported by SBIOS.
++ bit[1]=0: INT15 callback function Get boot display( ax=4e08, bl=01h) is not supported by SBIOS
++ =1: INT15 callback function Get boot display( ax=4e08, bl=01h) is supported by SBIOS
++ bit[2]=0: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is not supported by SBIOS
++ =1: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is supported by SBIOS
++ bit[3]=0: VBIOS fast boot is disable
++ =1: VBIOS fast boot is enable. ( VBIOS skip display device detection in every set mode if LCD panel is connect and LID is open)
++ulGPUCapInfo: bit[0]=0: TMDS/HDMI Coherent Mode use cascade PLL mode.
++ =1: TMDS/HDMI Coherent Mode use signel PLL mode.
++ bit[1]=0: DP mode use cascade PLL mode ( New for Trinity )
++ =1: DP mode use single PLL mode
++ bit[3]=0: Enable AUX HW mode detection logic
++ =1: Disable AUX HW mode detection logic
++
++ulSB_MMIO_Base_Addr: Physical Base address to SB MMIO space. Driver needs to initialize it for SMU usage.
++
++usRequestedPWMFreqInHz: When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW).
++ Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0;
++
++ When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below:
++ 1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use;
++ VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result,
++ Changing BL using VBIOS function is functional in both driver and non-driver present environment;
++ and enabling VariBri under the driver environment from PP table is optional.
++
++ 2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating
++ that BL control from GPU is expected.
++ VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1
++ Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but
++ it's per platform
++ and enabling VariBri under the driver environment from PP table is optional.
++
++ucHtcTmpLmt: Refer to D18F3x64 bit[22:16], HtcTmpLmt.
++ Threshold on value to enter HTC_active state.
++ucHtcHystLmt: Refer to D18F3x64 bit[27:24], HtcHystLmt.
++ To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt.
++ulMinEngineClock: Minimum SCLK allowed in 10kHz unit. This is calculated based on WRCK Fuse settings.
++ulSystemConfig: Bit[0]=0: PCIE Power Gating Disabled
++ =1: PCIE Power Gating Enabled
++ Bit[1]=0: DDR-DLL shut-down feature disabled.
++ 1: DDR-DLL shut-down feature enabled.
++ Bit[2]=0: DDR-PLL Power down feature disabled.
++ 1: DDR-PLL Power down feature enabled.
++ulCPUCapInfo: TBD
++usNBP0Voltage: VID for voltage on NB P0 State
++usNBP1Voltage: VID for voltage on NB P1 State
++usNBP2Voltage: VID for voltage on NB P2 State
++usNBP3Voltage: VID for voltage on NB P3 State
++usBootUpNBVoltage: Voltage Index of GNB voltage configured by SBIOS, which is suffcient to support VBIOS DISPCLK requirement.
++usExtDispConnInfoOffset: Offset to sExtDispConnInfo inside the structure
++usPanelRefreshRateRange: Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set
++ to indicate a range.
++ SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004
++ SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008
++ SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010
++ SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020
++ucMemoryType: [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved.
++ucUMAChannelNumber: System memory channel numbers.
++ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default
++ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback.
++ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications.
++sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high
+ ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns.
+ ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz.
+ ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz.
+@@ -4398,6 +4937,41 @@ usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%;
+ usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting.
+ usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting.
+ usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting.
++usMaxLVDSPclkFreqInSingleLink: Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz
++ucLVDSMisc: [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode
++ [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped
++ [bit2] LVDS 888bit per color mode =0: 666 bit per color =1:888 bit per color
++ [bit3] LVDS parameter override enable =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used
++ [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low )
++ucLVDSPwrOnSeqDIGONtoDE_in4Ms: LVDS power up sequence time in unit of 4ms, time delay from DIGON signal active to data enable signal active( DE ).
++ =0 mean use VBIOS default which is 8 ( 32ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON.
++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
++ucLVDSPwrOnDEtoVARY_BL_in4Ms: LVDS power up sequence time in unit of 4ms., time delay from DE( data enable ) active to Vary Brightness enable signal active( VARY_BL ).
++ =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON.
++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
++
++ucLVDSPwrOffVARY_BLtoDE_in4Ms: LVDS power down sequence time in unit of 4ms, time delay from data enable ( DE ) signal off to LCDVCC (DIGON) off.
++ =0 mean use VBIOS default delay which is 8 ( 32ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON
++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
++
++ucLVDSPwrOffDEtoDIGON_in4Ms: LVDS power down sequence time in unit of 4ms, time delay from vary brightness enable signal( VARY_BL) off to data enable ( DE ) signal off.
++ =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON
++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
++
++ucLVDSOffToOnDelay_in4Ms: LVDS power down sequence time in unit of 4ms. Time delay from DIGON signal off to DIGON signal active.
++ =0 means to use VBIOS default delay which is 125 ( 500ms ).
++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
++
++ucLVDSPwrOnVARY_BLtoBLON_in4Ms: LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active.
++ =0 means to use VBIOS default delay which is 0 ( 0ms ).
++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
++
++ucLVDSPwrOffBLONtoVARY_BL_in4Ms: LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off.
++ =0 means to use VBIOS default delay which is 0 ( 0ms ).
++ This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
++
++ulNbpStateMemclkFreq[4]: system memory clock frequncey in unit of 10Khz in different NB pstate.
++
+ **********************************************************************************************************************/
+
+ /**************************************************************************/
+@@ -4459,6 +5033,7 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT
+ #define ASIC_INTERNAL_SS_ON_DP 7
+ #define ASIC_INTERNAL_SS_ON_DCPLL 8
+ #define ASIC_EXTERNAL_SS_ON_DP_CLOCK 9
++#define ASIC_INTERNAL_VCE_SS 10
+
+ typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2
+ {
+@@ -4520,7 +5095,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3
+ #define ATOM_DOS_MODE_INFO_DEF 7
+ #define ATOM_I2C_CHANNEL_STATUS_DEF 8
+ #define ATOM_I2C_CHANNEL_STATUS1_DEF 9
+-
++#define ATOM_INTERNAL_TIMER_DEF 10
+
+ // BIOS_0_SCRATCH Definition
+ #define ATOM_S0_CRT1_MONO 0x00000001L
+@@ -4648,6 +5223,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3
+ #define ATOM_S2_DEVICE_DPMS_MASKw1 0x3FF
+ #define ATOM_S2_FORCEDLOWPWRMODE_STATE_MASKb3 0x0C
+ #define ATOM_S2_FORCEDLOWPWRMODE_STATE_CHANGEb3 0x10
++#define ATOM_S2_TMDS_COHERENT_MODEb3 0x10 // used by VBIOS code only, use coherent mode for TMDS/HDMI mode
+ #define ATOM_S2_VRI_BRIGHT_ENABLEb3 0x20
+ #define ATOM_S2_ROTATION_STATE_MASKb3 0xC0
+
+@@ -5038,6 +5614,23 @@ typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3
+ USHORT usDeviceId; // Active Device Id for this surface. If no device, set to 0.
+ }ENABLE_GRAPH_SURFACE_PARAMETERS_V1_3;
+
++typedef struct _ENABLE_GRAPH_SURFACE_PARAMETERS_V1_4
++{
++ USHORT usHight; // Image Hight
++ USHORT usWidth; // Image Width
++ USHORT usGraphPitch;
++ UCHAR ucColorDepth;
++ UCHAR ucPixelFormat;
++ UCHAR ucSurface; // Surface 1 or 2
++ UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE
++ UCHAR ucModeType;
++ UCHAR ucReserved;
++}ENABLE_GRAPH_SURFACE_PARAMETERS_V1_4;
++
++// ucEnable
++#define ATOM_GRAPH_CONTROL_SET_PITCH 0x0f
++#define ATOM_GRAPH_CONTROL_SET_DISP_START 0x10
++
+ typedef struct _ENABLE_GRAPH_SURFACE_PS_ALLOCATION
+ {
+ ENABLE_GRAPH_SURFACE_PARAMETERS sSetSurface;
+@@ -5057,6 +5650,58 @@ typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS
+ USHORT usY_Size;
+ }GET_DISPLAY_SURFACE_SIZE_PARAMETERS;
+
++typedef struct _GET_DISPLAY_SURFACE_SIZE_PARAMETERS_V2
++{
++ union{
++ USHORT usX_Size; //When use as input parameter, usX_Size indicates which CRTC
++ USHORT usSurface;
++ };
++ USHORT usY_Size;
++ USHORT usDispXStart;
++ USHORT usDispYStart;
++}GET_DISPLAY_SURFACE_SIZE_PARAMETERS_V2;
++
++
++typedef struct _PALETTE_DATA_CONTROL_PARAMETERS_V3
++{
++ UCHAR ucLutId;
++ UCHAR ucAction;
++ USHORT usLutStartIndex;
++ USHORT usLutLength;
++ USHORT usLutOffsetInVram;
++}PALETTE_DATA_CONTROL_PARAMETERS_V3;
++
++// ucAction:
++#define PALETTE_DATA_AUTO_FILL 1
++#define PALETTE_DATA_READ 2
++#define PALETTE_DATA_WRITE 3
++
++
++typedef struct _INTERRUPT_SERVICE_PARAMETERS_V2
++{
++ UCHAR ucInterruptId;
++ UCHAR ucServiceId;
++ UCHAR ucStatus;
++ UCHAR ucReserved;
++}INTERRUPT_SERVICE_PARAMETER_V2;
++
++// ucInterruptId
++#define HDP1_INTERRUPT_ID 1
++#define HDP2_INTERRUPT_ID 2
++#define HDP3_INTERRUPT_ID 3
++#define HDP4_INTERRUPT_ID 4
++#define HDP5_INTERRUPT_ID 5
++#define HDP6_INTERRUPT_ID 6
++#define SW_INTERRUPT_ID 11
++
++// ucAction
++#define INTERRUPT_SERVICE_GEN_SW_INT 1
++#define INTERRUPT_SERVICE_GET_STATUS 2
++
++ // ucStatus
++#define INTERRUPT_STATUS__INT_TRIGGER 1
++#define INTERRUPT_STATUS__HPD_HIGH 2
++
+ typedef struct _INDIRECT_IO_ACCESS
+ {
+ ATOM_COMMON_TABLE_HEADER sHeader;
+@@ -5189,7 +5834,7 @@ typedef struct _ATOM_INIT_REG_BLOCK{
+
+ #define END_OF_REG_INDEX_BLOCK 0x0ffff
+ #define END_OF_REG_DATA_BLOCK 0x00000000
+-#define ATOM_INIT_REG_MASK_FLAG 0x80
++#define ATOM_INIT_REG_MASK_FLAG 0x80 //Not used in BIOS
+ #define CLOCK_RANGE_HIGHEST 0x00ffffff
+
+ #define VALUE_DWORD SIZEOF ULONG
+@@ -5229,6 +5874,7 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE
+ #define _128Mx8 0x51
+ #define _128Mx16 0x52
+ #define _256Mx8 0x61
++#define _256Mx16 0x62
+
+ #define SAMSUNG 0x1
+ #define INFINEON 0x2
+@@ -5585,7 +6231,7 @@ typedef struct _ATOM_VRAM_MODULE_V7
+ ULONG ulChannelMapCfg; // mmMC_SHARED_CHREMAP
+ USHORT usModuleSize; // Size of ATOM_VRAM_MODULE_V7
+ USHORT usPrivateReserved; // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS)
+- USHORT usReserved;
++ USHORT usEnableChannels; // bit vector which indicate which channels are enabled
+ UCHAR ucExtMemoryID; // Current memory module ID
+ UCHAR ucMemoryType; // MEM_TYPE_DDR2/DDR3/GDDR3/GDDR5
+ UCHAR ucChannelNum; // Number of mem. channels supported in this module
+@@ -5597,7 +6243,8 @@ typedef struct _ATOM_VRAM_MODULE_V7
+ UCHAR ucNPL_RT; // Round trip delay (MC_SEQ_CAS_TIMING [28:24]:TCL=CL+NPL_RT-2). Always 2.
+ UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble
+ UCHAR ucMemorySize; // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros
+- UCHAR ucReserved[3];
++ USHORT usSEQSettingOffset;
++ UCHAR ucReserved;
+ // Memory Module specific values
+ USHORT usEMRS2Value; // EMRS2/MR2 Value.
+ USHORT usEMRS3Value; // EMRS3/MR3 Value.
+@@ -5633,10 +6280,10 @@ typedef struct _ATOM_VRAM_INFO_V3
+ typedef struct _ATOM_VRAM_INFO_V4
+ {
+ ATOM_COMMON_TABLE_HEADER sHeader;
+- USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting
+- USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting
+- USHORT usRerseved;
+- UCHAR ucMemDQ7_0ByteRemap; // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3
++ USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting
++ USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting
++ USHORT usRerseved;
++ UCHAR ucMemDQ7_0ByteRemap; // DQ line byte remap, =0: Memory Data line BYTE0, =1: BYTE1, =2: BYTE2, =3: BYTE3
+ ULONG ulMemDQ7_0BitRemap; // each DQ line ( 7~0) use 3bits, like: DQ0=Bit[2:0], DQ1:[5:3], ... DQ7:[23:21]
+ UCHAR ucReservde[4];
+ UCHAR ucNumOfVRAMModule;
+@@ -5648,9 +6295,10 @@ typedef struct _ATOM_VRAM_INFO_V4
+ typedef struct _ATOM_VRAM_INFO_HEADER_V2_1
+ {
+ ATOM_COMMON_TABLE_HEADER sHeader;
+- USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting
+- USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting
+- USHORT usReserved[4];
++ USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting
++ USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting
++ USHORT usPerBytePresetOffset; // offset of ATOM_INIT_REG_BLOCK structure for Per Byte Offset Preset Settings
++ USHORT usReserved[3];
+ UCHAR ucNumOfVRAMModule; // indicate number of VRAM module
+ UCHAR ucMemoryClkPatchTblVer; // version of memory AC timing register list
+ UCHAR ucVramModuleVer; // indicate ATOM_VRAM_MODUE version
+@@ -5935,6 +6583,52 @@ typedef struct _ATOM_DISP_OUT_INFO_V2
+ ASIC_ENCODER_INFO asEncoderInfo[1];
+ }ATOM_DISP_OUT_INFO_V2;
+
++
++typedef struct _ATOM_DISP_CLOCK_ID {
++ UCHAR ucPpllId;
++ UCHAR ucPpllAttribute;
++}ATOM_DISP_CLOCK_ID;
++
++// ucPpllAttribute
++#define CLOCK_SOURCE_SHAREABLE 0x01
++#define CLOCK_SOURCE_DP_MODE 0x02
++#define CLOCK_SOURCE_NONE_DP_MODE 0x04
++
++//DispOutInfoTable
++typedef struct _ASIC_TRANSMITTER_INFO_V2
++{
++ USHORT usTransmitterObjId;
++ USHORT usDispClkIdOffset; // point to clock source id list supported by Encoder Object
++ UCHAR ucTransmitterCmdTblId;
++ UCHAR ucConfig;
++ UCHAR ucEncoderID; // available 1st encoder ( default )
++ UCHAR ucOptionEncoderID; // available 2nd encoder ( optional )
++ UCHAR uc2ndEncoderID;
++ UCHAR ucReserved;
++}ASIC_TRANSMITTER_INFO_V2;
++
++typedef struct _ATOM_DISP_OUT_INFO_V3
++{
++ ATOM_COMMON_TABLE_HEADER sHeader;
++ USHORT ptrTransmitterInfo;
++ USHORT ptrEncoderInfo;
++ USHORT ptrMainCallParserFar; // direct address of main parser call in VBIOS binary.
++ USHORT usReserved;
++ UCHAR ucDCERevision;
++ UCHAR ucMaxDispEngineNum;
++ UCHAR ucMaxActiveDispEngineNum;
++ UCHAR ucMaxPPLLNum;
++ UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE
++ UCHAR ucReserved[3];
++ ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only
++}ATOM_DISP_OUT_INFO_V3;
++
++typedef enum CORE_REF_CLK_SOURCE{
++ CLOCK_SRC_XTALIN=0,
++ CLOCK_SRC_XO_IN=1,
++ CLOCK_SRC_XO_IN2=2,
++}CORE_REF_CLK_SOURCE;
++
+ // DispDevicePriorityInfo
+ typedef struct _ATOM_DISPLAY_DEVICE_PRIORITY_INFO
+ {
+@@ -6070,6 +6764,39 @@ typedef struct _PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS
+ #define HW_I2C_READ 0
+ #define I2C_2BYTE_ADDR 0x02
+
++/****************************************************************************/
++// Structures used by HW_Misc_OperationTable
++/****************************************************************************/
++typedef struct _ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1
++{
++ UCHAR ucCmd; // Input: To tell which action to take
++ UCHAR ucReserved[3];
++ ULONG ulReserved;
++}ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1;
++
++typedef struct _ATOM_HW_MISC_OPERATION_OUTPUT_PARAMETER_V1_1
++{
++ UCHAR ucReturnCode; // Output: Return value base on action was taken
++ UCHAR ucReserved[3];
++ ULONG ulReserved;
++}ATOM_HW_MISC_OPERATION_OUTPUT_PARAMETER_V1_1;
++
++// Actions code
++#define ATOM_GET_SDI_SUPPORT 0xF0
++
++// Return code
++#define ATOM_UNKNOWN_CMD 0
++#define ATOM_FEATURE_NOT_SUPPORTED 1
++#define ATOM_FEATURE_SUPPORTED 2
++
++typedef struct _ATOM_HW_MISC_OPERATION_PS_ALLOCATION
++{
++ ATOM_HW_MISC_OPERATION_INPUT_PARAMETER_V1_1 sInput_Output;
++ PROCESS_I2C_CHANNEL_TRANSACTION_PARAMETERS sReserved;
++}ATOM_HW_MISC_OPERATION_PS_ALLOCATION;
++
++/****************************************************************************/
++
+ typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2
+ {
+ UCHAR ucHWBlkInst; // HW block instance, 0, 1, 2, ...
+@@ -6090,6 +6817,52 @@ typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2
+ #define SELECT_CRTC_PIXEL_RATE 7
+ #define SELECT_VGA_BLK 8
+
++// DIGTransmitterInfoTable structure used to program UNIPHY settings
++typedef struct _DIG_TRANSMITTER_INFO_HEADER_V3_1{
++ ATOM_COMMON_TABLE_HEADER sHeader;
++ USHORT usDPVsPreEmphSettingOffset; // offset of PHY_ANALOG_SETTING_INFO * with DP Voltage Swing and Pre-Emphasis for each Link clock
++ USHORT usPhyAnalogRegListOffset; // offset of CLOCK_CONDITION_REGESTER_INFO* with None-DP mode Analog Setting's register Info
++ USHORT usPhyAnalogSettingOffset; // offset of CLOCK_CONDITION_SETTING_ENTRY* with None-DP mode Analog Setting for each link clock range
++ USHORT usPhyPllRegListOffset; // offset of CLOCK_CONDITION_REGESTER_INFO* with Phy Pll register Info
++ USHORT usPhyPllSettingOffset; // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy Pll Settings
++}DIG_TRANSMITTER_INFO_HEADER_V3_1;
++
++typedef struct _CLOCK_CONDITION_REGESTER_INFO{
++ USHORT usRegisterIndex;
++ UCHAR ucStartBit;
++ UCHAR ucEndBit;
++}CLOCK_CONDITION_REGESTER_INFO;
++
++typedef struct _CLOCK_CONDITION_SETTING_ENTRY{
++ USHORT usMaxClockFreq;
++ UCHAR ucEncodeMode;
++ UCHAR ucPhySel;
++ ULONG ulAnalogSetting[1];
++}CLOCK_CONDITION_SETTING_ENTRY;
++
++typedef struct _CLOCK_CONDITION_SETTING_INFO{
++ USHORT usEntrySize;
++ CLOCK_CONDITION_SETTING_ENTRY asClkCondSettingEntry[1];
++}CLOCK_CONDITION_SETTING_INFO;
++
++typedef struct _PHY_CONDITION_REG_VAL{
++ ULONG ulCondition;
++ ULONG ulRegVal;
++}PHY_CONDITION_REG_VAL;
++
++typedef struct _PHY_CONDITION_REG_INFO{
++ USHORT usRegIndex;
++ USHORT usSize;
++ PHY_CONDITION_REG_VAL asRegVal[1];
++}PHY_CONDITION_REG_INFO;
++
++typedef struct _PHY_ANALOG_SETTING_INFO{
++ UCHAR ucEncodeMode;
++ UCHAR ucPhySel;
++ USHORT usSize;
++ PHY_CONDITION_REG_INFO asAnalogSetting[1];
++}PHY_ANALOG_SETTING_INFO;
++
+ /****************************************************************************/
+ //Portion VI: Definitinos for vbios MC scratch registers that driver used
+ /****************************************************************************/
+@@ -7020,4 +7793,68 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table
+
+ #pragma pack() // BIOS data must use byte aligment
+
++//
++// AMD ACPI Table
++//
++#pragma pack(1)
++
++typedef struct {
++ ULONG Signature;
++ ULONG TableLength; //Length
++ UCHAR Revision;
++ UCHAR Checksum;
++ UCHAR OemId[6];
++ UCHAR OemTableId[8]; //UINT64 OemTableId;
++ ULONG OemRevision;
++ ULONG CreatorId;
++ ULONG CreatorRevision;
++} AMD_ACPI_DESCRIPTION_HEADER;
++/*
++//EFI_ACPI_DESCRIPTION_HEADER from AcpiCommon.h
++typedef struct {
++ UINT32 Signature; //0x0
++ UINT32 Length; //0x4
++ UINT8 Revision; //0x8
++ UINT8 Checksum; //0x9
++ UINT8 OemId[6]; //0xA
++ UINT64 OemTableId; //0x10
++ UINT32 OemRevision; //0x18
++ UINT32 CreatorId; //0x1C
++ UINT32 CreatorRevision; //0x20
++}EFI_ACPI_DESCRIPTION_HEADER;
++*/
++typedef struct {
++ AMD_ACPI_DESCRIPTION_HEADER SHeader;
++ UCHAR TableUUID[16]; //0x24
++ ULONG VBIOSImageOffset; //0x34. Offset to the first GOP_VBIOS_CONTENT block from the beginning of the stucture.
++ ULONG Lib1ImageOffset; //0x38. Offset to the first GOP_LIB1_CONTENT block from the beginning of the stucture.
++ ULONG Reserved[4]; //0x3C
++}UEFI_ACPI_VFCT;
++
++typedef struct {
++ ULONG PCIBus; //0x4C
++ ULONG PCIDevice; //0x50
++ ULONG PCIFunction; //0x54
++ USHORT VendorID; //0x58
++ USHORT DeviceID; //0x5A
++ USHORT SSVID; //0x5C
++ USHORT SSID; //0x5E
++ ULONG Revision; //0x60
++ ULONG ImageLength; //0x64
++}VFCT_IMAGE_HEADER;
++
++
++typedef struct {
++ VFCT_IMAGE_HEADER VbiosHeader;
++ UCHAR VbiosContent[1];
++}GOP_VBIOS_CONTENT;
++
++typedef struct {
++ VFCT_IMAGE_HEADER Lib1Header;
++ UCHAR Lib1Content[1];
++}GOP_LIB1_CONTENT;
++
++#pragma pack()
++
++
+ #endif /* _ATOMBIOS_H */
+diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
+index 8227e76..28e69e9 100644
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -123,21 +123,6 @@ struct radeon_device;
+ /*
+ * BIOS.
+ */
+-#define ATRM_BIOS_PAGE 4096
+-
+-#if defined(CONFIG_VGA_SWITCHEROO)
+-bool radeon_atrm_supported(struct pci_dev *pdev);
+-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
+-#else
+-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
+-{
+- return false;
+-}
+-
+-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
+- return -EINVAL;
+-}
+-#endif
+ bool radeon_get_bios(struct radeon_device *rdev);
+
+
+diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
+index 9d2c369..38585c5 100644
+--- a/drivers/gpu/drm/radeon/radeon_atombios.c
++++ b/drivers/gpu/drm/radeon/radeon_atombios.c
+@@ -446,7 +446,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
+ }
+
+ /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */
+- if ((dev->pdev->device == 0x9802) &&
++ if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) &&
+ (dev->pdev->subsystem_vendor == 0x1734) &&
+ (dev->pdev->subsystem_device == 0x11bd)) {
+ if (*connector_type == DRM_MODE_CONNECTOR_VGA) {
+diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+index 9d95792..2a2cf0b 100644
+--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+@@ -30,56 +30,8 @@ static struct radeon_atpx_priv {
+ /* handle for device - and atpx */
+ acpi_handle dhandle;
+ acpi_handle atpx_handle;
+- acpi_handle atrm_handle;
+ } radeon_atpx_priv;
+
+-/* retrieve the ROM in 4k blocks */
+-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+- int offset, int len)
+-{
+- acpi_status status;
+- union acpi_object atrm_arg_elements[2], *obj;
+- struct acpi_object_list atrm_arg;
+- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+-
+- atrm_arg.count = 2;
+- atrm_arg.pointer = &atrm_arg_elements[0];
+-
+- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
+- atrm_arg_elements[0].integer.value = offset;
+-
+- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
+- atrm_arg_elements[1].integer.value = len;
+-
+- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
+- if (ACPI_FAILURE(status)) {
+- printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
+- return -ENODEV;
+- }
+-
+- obj = (union acpi_object *)buffer.pointer;
+- memcpy(bios+offset, obj->buffer.pointer, len);
+- kfree(buffer.pointer);
+- return len;
+-}
+-
+-bool radeon_atrm_supported(struct pci_dev *pdev)
+-{
+- /* get the discrete ROM only via ATRM */
+- if (!radeon_atpx_priv.atpx_detected)
+- return false;
+-
+- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
+- return false;
+- return true;
+-}
+-
+-
+-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
+-{
+- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
+-}
+-
+ static int radeon_atpx_get_version(acpi_handle handle)
+ {
+ acpi_status status;
+@@ -197,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
+
+ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
+ {
+- acpi_handle dhandle, atpx_handle, atrm_handle;
++ acpi_handle dhandle, atpx_handle;
+ acpi_status status;
+
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+@@ -208,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
+ if (ACPI_FAILURE(status))
+ return false;
+
+- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
+- if (ACPI_FAILURE(status))
+- return false;
+-
+ radeon_atpx_priv.dhandle = dhandle;
+ radeon_atpx_priv.atpx_handle = atpx_handle;
+- radeon_atpx_priv.atrm_handle = atrm_handle;
+ return true;
+ }
+
+diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
+index 229a20f..d306cc8 100644
+--- a/drivers/gpu/drm/radeon/radeon_bios.c
++++ b/drivers/gpu/drm/radeon/radeon_bios.c
+@@ -32,6 +32,7 @@
+
+ #include <linux/vga_switcheroo.h>
+ #include <linux/slab.h>
++#include <linux/acpi.h>
+ /*
+ * BIOS.
+ */
+@@ -98,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
+ return true;
+ }
+
++#ifdef CONFIG_ACPI
+ /* ATRM is used to get the BIOS on the discrete cards in
+ * dual-gpu systems.
+ */
++/* retrieve the ROM in 4k blocks */
++#define ATRM_BIOS_PAGE 4096
++/**
++ * radeon_atrm_call - fetch a chunk of the vbios
++ *
++ * @atrm_handle: acpi ATRM handle
++ * @bios: vbios image pointer
++ * @offset: offset of vbios image data to fetch
++ * @len: length of vbios image data to fetch
++ *
++ * Executes ATRM to fetch a chunk of the discrete
++ * vbios image on PX systems (all asics).
++ * Returns the length of the buffer fetched.
++ */
++static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
++ int offset, int len)
++{
++ acpi_status status;
++ union acpi_object atrm_arg_elements[2], *obj;
++ struct acpi_object_list atrm_arg;
++ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
++
++ atrm_arg.count = 2;
++ atrm_arg.pointer = &atrm_arg_elements[0];
++
++ atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
++ atrm_arg_elements[0].integer.value = offset;
++
++ atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
++ atrm_arg_elements[1].integer.value = len;
++
++ status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
++ if (ACPI_FAILURE(status)) {
++ printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
++ return -ENODEV;
++ }
++
++ obj = (union acpi_object *)buffer.pointer;
++ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
++ len = obj->buffer.length;
++ kfree(buffer.pointer);
++ return len;
++}
++
+ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+ {
+ int ret;
+ int size = 256 * 1024;
+ int i;
++ struct pci_dev *pdev = NULL;
++ acpi_handle dhandle, atrm_handle;
++ acpi_status status;
++ bool found = false;
++
++ /* ATRM is for the discrete card only */
++ if (rdev->flags & RADEON_IS_IGP)
++ return false;
++
++ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
++ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
++ if (!dhandle)
++ continue;
++
++ status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
++ if (!ACPI_FAILURE(status)) {
++ found = true;
++ break;
++ }
++ }
+
+- if (!radeon_atrm_supported(rdev->pdev))
++ if (!found)
+ return false;
+
+ rdev->bios = kmalloc(size, GFP_KERNEL);
+@@ -117,10 +183,11 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+ }
+
+ for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
+- ret = radeon_atrm_get_bios_chunk(rdev->bios,
+- (i * ATRM_BIOS_PAGE),
+- ATRM_BIOS_PAGE);
+- if (ret <= 0)
++ ret = radeon_atrm_call(atrm_handle,
++ rdev->bios,
++ (i * ATRM_BIOS_PAGE),
++ ATRM_BIOS_PAGE);
++ if (ret < ATRM_BIOS_PAGE)
+ break;
+ }
+
+@@ -130,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+ }
+ return true;
+ }
++#else
++static inline bool radeon_atrm_get_bios(struct radeon_device *rdev)
++{
++ return false;
++}
++#endif
+
+ static bool ni_read_disabled_bios(struct radeon_device *rdev)
+ {
+@@ -476,6 +549,61 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
+ return legacy_read_disabled_bios(rdev);
+ }
+
++#ifdef CONFIG_ACPI
++static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
++{
++ bool ret = false;
++ struct acpi_table_header *hdr;
++ acpi_size tbl_size;
++ UEFI_ACPI_VFCT *vfct;
++ GOP_VBIOS_CONTENT *vbios;
++ VFCT_IMAGE_HEADER *vhdr;
++
++ if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
++ return false;
++ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
++ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
++ goto out_unmap;
++ }
++
++ vfct = (UEFI_ACPI_VFCT *)hdr;
++ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
++ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
++ goto out_unmap;
++ }
++
++ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
++ vhdr = &vbios->VbiosHeader;
++ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
++ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
++ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
++
++ if (vhdr->PCIBus != rdev->pdev->bus->number ||
++ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
++ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
++ vhdr->VendorID != rdev->pdev->vendor ||
++ vhdr->DeviceID != rdev->pdev->device) {
++ DRM_INFO("ACPI VFCT table is not for this card\n");
++ goto out_unmap;
++ };
++
++ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
++ DRM_ERROR("ACPI VFCT image truncated\n");
++ goto out_unmap;
++ }
++
++ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
++ ret = !!rdev->bios;
++
++out_unmap:
++ return ret;
++}
++#else
++static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
++{
++ return false;
++}
++#endif
+
+ bool radeon_get_bios(struct radeon_device *rdev)
+ {
+@@ -484,6 +612,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
+
+ r = radeon_atrm_get_bios(rdev);
+ if (r == false)
++ r = radeon_acpi_vfct_bios(rdev);
++ if (r == false)
+ r = igp_read_bios_from_vram(rdev);
+ if (r == false)
+ r = radeon_read_bios(rdev);
+diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
+index 39497c7..f3ae607 100644
+--- a/drivers/gpu/drm/radeon/radeon_object.c
++++ b/drivers/gpu/drm/radeon/radeon_object.c
+@@ -117,6 +117,7 @@ int radeon_bo_create(struct radeon_device *rdev,
+ return -ENOMEM;
+ }
+
++retry:
+ bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
+ if (bo == NULL)
+ return -ENOMEM;
+@@ -129,8 +130,6 @@ int radeon_bo_create(struct radeon_device *rdev,
+ bo->gem_base.driver_private = NULL;
+ bo->surface_reg = -1;
+ INIT_LIST_HEAD(&bo->list);
+-
+-retry:
+ radeon_ttm_placement_from_domain(bo, domain);
+ /* Kernel allocation are uninterruptible */
+ mutex_lock(&rdev->vram_mutex);
+diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
+index b99af34..a2abb8e 100644
+--- a/drivers/hid/hid-chicony.c
++++ b/drivers/hid/hid-chicony.c
+@@ -60,6 +60,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+ static const struct hid_device_id ch_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
+ { }
+ };
+ MODULE_DEVICE_TABLE(hid, ch_devices);
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 95430a0..5cc029f 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1398,12 +1398,14 @@ static const struct hid_device_id hid_have_special_driver[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
+diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
+index 2f0be4c..9e43aac 100644
+--- a/drivers/hid/hid-cypress.c
++++ b/drivers/hid/hid-cypress.c
+@@ -129,6 +129,8 @@ static const struct hid_device_id cp_devices[] = {
+ .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3),
+ .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
++ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4),
++ .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
+ .driver_data = CP_2WHEEL_MOUSE_HACK },
+ { }
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 7db934d..e4317a2 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -196,6 +196,7 @@
+ #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
+ #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
+ #define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123
++#define USB_DEVICE_ID_CHICONY_AK1D 0x1125
+
+ #define USB_VENDOR_ID_CHUNGHWAT 0x2247
+ #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
+@@ -225,6 +226,7 @@
+ #define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
+ #define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
+ #define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1
++#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81
+ #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001
+
+ #define USB_VENDOR_ID_DEALEXTREAME 0x10c5
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index 0bfa545..c76b051 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -568,24 +568,62 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
+ scmnd->sc_data_direction);
+ }
+
+-static void srp_remove_req(struct srp_target_port *target,
+- struct srp_request *req, s32 req_lim_delta)
++/**
++ * srp_claim_req - Take ownership of the scmnd associated with a request.
++ * @target: SRP target port.
++ * @req: SRP request.
++ * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take
++ * ownership of @req->scmnd if it equals @scmnd.
++ *
++ * Return value:
++ * Either NULL or a pointer to the SCSI command the caller became owner of.
++ */
++static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target,
++ struct srp_request *req,
++ struct scsi_cmnd *scmnd)
+ {
+ unsigned long flags;
+
+- srp_unmap_data(req->scmnd, target, req);
++ spin_lock_irqsave(&target->lock, flags);
++ if (!scmnd) {
++ scmnd = req->scmnd;
++ req->scmnd = NULL;
++ } else if (req->scmnd == scmnd) {
++ req->scmnd = NULL;
++ } else {
++ scmnd = NULL;
++ }
++ spin_unlock_irqrestore(&target->lock, flags);
++
++ return scmnd;
++}
++
++/**
++ * srp_free_req() - Unmap data and add request to the free request list.
++ */
++static void srp_free_req(struct srp_target_port *target,
++ struct srp_request *req, struct scsi_cmnd *scmnd,
++ s32 req_lim_delta)
++{
++ unsigned long flags;
++
++ srp_unmap_data(scmnd, target, req);
++
+ spin_lock_irqsave(&target->lock, flags);
+ target->req_lim += req_lim_delta;
+- req->scmnd = NULL;
+ list_add_tail(&req->list, &target->free_reqs);
+ spin_unlock_irqrestore(&target->lock, flags);
+ }
+
+ static void srp_reset_req(struct srp_target_port *target, struct srp_request *req)
+ {
+- req->scmnd->result = DID_RESET << 16;
+- req->scmnd->scsi_done(req->scmnd);
+- srp_remove_req(target, req, 0);
++ struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL);
++
++ if (scmnd) {
++ scmnd->result = DID_RESET << 16;
++ scmnd->scsi_done(scmnd);
++ srp_free_req(target, req, scmnd, 0);
++ }
+ }
+
+ static int srp_reconnect_target(struct srp_target_port *target)
+@@ -1055,11 +1093,18 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
+ complete(&target->tsk_mgmt_done);
+ } else {
+ req = &target->req_ring[rsp->tag];
+- scmnd = req->scmnd;
+- if (!scmnd)
++ scmnd = srp_claim_req(target, req, NULL);
++ if (!scmnd) {
+ shost_printk(KERN_ERR, target->scsi_host,
+ "Null scmnd for RSP w/tag %016llx\n",
+ (unsigned long long) rsp->tag);
++
++ spin_lock_irqsave(&target->lock, flags);
++ target->req_lim += be32_to_cpu(rsp->req_lim_delta);
++ spin_unlock_irqrestore(&target->lock, flags);
++
++ return;
++ }
+ scmnd->result = rsp->status;
+
+ if (rsp->flags & SRP_RSP_FLAG_SNSVALID) {
+@@ -1074,7 +1119,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
+ else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER))
+ scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt));
+
+- srp_remove_req(target, req, be32_to_cpu(rsp->req_lim_delta));
++ srp_free_req(target, req, scmnd,
++ be32_to_cpu(rsp->req_lim_delta));
++
+ scmnd->host_scribble = NULL;
+ scmnd->scsi_done(scmnd);
+ }
+@@ -1613,25 +1660,17 @@ static int srp_abort(struct scsi_cmnd *scmnd)
+ {
+ struct srp_target_port *target = host_to_target(scmnd->device->host);
+ struct srp_request *req = (struct srp_request *) scmnd->host_scribble;
+- int ret = SUCCESS;
+
+ shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
+
+- if (!req || target->qp_in_error)
+- return FAILED;
+- if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
+- SRP_TSK_ABORT_TASK))
++ if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd))
+ return FAILED;
++ srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
++ SRP_TSK_ABORT_TASK);
++ srp_free_req(target, req, scmnd, 0);
++ scmnd->result = DID_ABORT << 16;
+
+- if (req->scmnd) {
+- if (!target->tsk_mgmt_status) {
+- srp_remove_req(target, req, 0);
+- scmnd->result = DID_ABORT << 16;
+- } else
+- ret = FAILED;
+- }
+-
+- return ret;
++ return SUCCESS;
+ }
+
+ static int srp_reset_device(struct scsi_cmnd *scmnd)
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index d8646d7..2887f22 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -1144,8 +1144,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
+ ret = 0;
+ }
+ rdev->sectors = rdev->sb_start;
+- /* Limit to 4TB as metadata cannot record more than that */
+- if (rdev->sectors >= (2ULL << 32))
++ /* Limit to 4TB as metadata cannot record more than that.
++ * (not needed for Linear and RAID0 as metadata doesn't
++ * record this size)
++ */
++ if (rdev->sectors >= (2ULL << 32) && sb->level >= 1)
+ rdev->sectors = (2ULL << 32) - 2;
+
+ if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1)
+@@ -1427,7 +1430,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)
+ /* Limit to 4TB as metadata cannot record more than that.
+ * 4TB == 2^32 KB, or 2*2^32 sectors.
+ */
+- if (num_sectors >= (2ULL << 32))
++ if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1)
+ num_sectors = (2ULL << 32) - 2;
+ md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,
+ rdev->sb_page);
+diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
+index fb68805..027550d 100644
+--- a/drivers/media/dvb/siano/smsusb.c
++++ b/drivers/media/dvb/siano/smsusb.c
+@@ -481,7 +481,7 @@ static int smsusb_resume(struct usb_interface *intf)
+ return 0;
+ }
+
+-static const struct usb_device_id smsusb_id_table[] __devinitconst = {
++static const struct usb_device_id smsusb_id_table[] = {
+ { USB_DEVICE(0x187f, 0x0010),
+ .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+ { USB_DEVICE(0x187f, 0x0100),
+diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
+index 89fec4c..731cd16 100644
+--- a/drivers/media/video/gspca/spca506.c
++++ b/drivers/media/video/gspca/spca506.c
+@@ -685,7 +685,7 @@ static const struct sd_desc sd_desc = {
+ };
+
+ /* -- module initialisation -- */
+-static const struct usb_device_id device_table[] __devinitconst = {
++static const struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x06e1, 0xa190)},
+ /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505
+ {USB_DEVICE(0x0733, 0x0430)}, */
+diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
+index 17bbacb..cc2ae7e 100644
+--- a/drivers/misc/sgi-xp/xpc_uv.c
++++ b/drivers/misc/sgi-xp/xpc_uv.c
+@@ -18,6 +18,8 @@
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
++#include <linux/cpu.h>
++#include <linux/module.h>
+ #include <linux/err.h>
+ #include <linux/slab.h>
+ #include <asm/uv/uv_hub.h>
+@@ -59,6 +61,8 @@ static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
+ XPC_NOTIFY_MSG_SIZE_UV)
+ #define XPC_NOTIFY_IRQ_NAME "xpc_notify"
+
++static int xpc_mq_node = -1;
++
+ static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
+ static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
+
+@@ -109,11 +113,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
+ #if defined CONFIG_X86_64
+ mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
+ UV_AFFINITY_CPU);
+- if (mq->irq < 0) {
+- dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
+- -mq->irq);
++ if (mq->irq < 0)
+ return mq->irq;
+- }
+
+ mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
+
+@@ -238,8 +239,9 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
+ mq->mmr_blade = uv_cpu_to_blade_id(cpu);
+
+ nid = cpu_to_node(cpu);
+- page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+- pg_order);
++ page = alloc_pages_exact_node(nid,
++ GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
++ pg_order);
+ if (page == NULL) {
+ dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
+ "bytes of memory on nid=%d for GRU mq\n", mq_size, nid);
+@@ -1731,9 +1733,50 @@ static struct xpc_arch_operations xpc_arch_ops_uv = {
+ .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
+ };
+
++static int
++xpc_init_mq_node(int nid)
++{
++ int cpu;
++
++ get_online_cpus();
++
++ for_each_cpu(cpu, cpumask_of_node(nid)) {
++ xpc_activate_mq_uv =
++ xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid,
++ XPC_ACTIVATE_IRQ_NAME,
++ xpc_handle_activate_IRQ_uv);
++ if (!IS_ERR(xpc_activate_mq_uv))
++ break;
++ }
++ if (IS_ERR(xpc_activate_mq_uv)) {
++ put_online_cpus();
++ return PTR_ERR(xpc_activate_mq_uv);
++ }
++
++ for_each_cpu(cpu, cpumask_of_node(nid)) {
++ xpc_notify_mq_uv =
++ xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid,
++ XPC_NOTIFY_IRQ_NAME,
++ xpc_handle_notify_IRQ_uv);
++ if (!IS_ERR(xpc_notify_mq_uv))
++ break;
++ }
++ if (IS_ERR(xpc_notify_mq_uv)) {
++ xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
++ put_online_cpus();
++ return PTR_ERR(xpc_notify_mq_uv);
++ }
++
++ put_online_cpus();
++ return 0;
++}
++
+ int
+ xpc_init_uv(void)
+ {
++ int nid;
++ int ret = 0;
++
+ xpc_arch_ops = xpc_arch_ops_uv;
+
+ if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
+@@ -1742,21 +1785,21 @@ xpc_init_uv(void)
+ return -E2BIG;
+ }
+
+- xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0,
+- XPC_ACTIVATE_IRQ_NAME,
+- xpc_handle_activate_IRQ_uv);
+- if (IS_ERR(xpc_activate_mq_uv))
+- return PTR_ERR(xpc_activate_mq_uv);
++ if (xpc_mq_node < 0)
++ for_each_online_node(nid) {
++ ret = xpc_init_mq_node(nid);
+
+- xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0,
+- XPC_NOTIFY_IRQ_NAME,
+- xpc_handle_notify_IRQ_uv);
+- if (IS_ERR(xpc_notify_mq_uv)) {
+- xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
+- return PTR_ERR(xpc_notify_mq_uv);
+- }
++ if (!ret)
++ break;
++ }
++ else
++ ret = xpc_init_mq_node(xpc_mq_node);
+
+- return 0;
++ if (ret < 0)
++ dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n",
++ -ret);
++
++ return ret;
+ }
+
+ void
+@@ -1765,3 +1808,6 @@ xpc_exit_uv(void)
+ xpc_destroy_gru_mq_uv(xpc_notify_mq_uv);
+ xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
+ }
++
++module_param(xpc_mq_node, int, 0);
++MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues.");
+diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
+index e888202..01b104e 100644
+--- a/drivers/net/netconsole.c
++++ b/drivers/net/netconsole.c
+@@ -652,7 +652,6 @@ static int netconsole_netdev_event(struct notifier_block *this,
+ flags);
+ dev_put(nt->np.dev);
+ nt->np.dev = NULL;
+- netconsole_target_put(nt);
+ }
+ nt->enabled = 0;
+ stopped = true;
+diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
+index e6d791c..b4cbc82 100644
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -1782,7 +1782,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
+ struct ieee80211_hw *hw = sc->hw;
+ struct ieee80211_hdr *hdr;
+ int retval;
+- bool decrypt_error = false;
+ struct ath_rx_status rs;
+ enum ath9k_rx_qtype qtype;
+ bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
+@@ -1804,6 +1803,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
+ tsf_lower = tsf & 0xffffffff;
+
+ do {
++ bool decrypt_error = false;
+ /* If handling rx interrupt and flush is in progress => exit */
+ if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
+ break;
+diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
+index 9b60968..8a009bc 100644
+--- a/drivers/net/wireless/p54/p54usb.c
++++ b/drivers/net/wireless/p54/p54usb.c
+@@ -42,7 +42,7 @@ MODULE_FIRMWARE("isl3887usb");
+ * whenever you add a new device.
+ */
+
+-static struct usb_device_id p54u_table[] __devinitdata = {
++static struct usb_device_id p54u_table[] = {
+ /* Version 1 devices (pci chip + net2280) */
+ {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */
+ {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
+diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
+index 4a78f9e..4e98c39 100644
+--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
++++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
+@@ -44,7 +44,7 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
+ MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
+ MODULE_LICENSE("GPL");
+
+-static struct usb_device_id rtl8187_table[] __devinitdata = {
++static struct usb_device_id rtl8187_table[] = {
+ /* Asus */
+ {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
+ /* Belkin */
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index d024f83..68af94c 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -952,6 +952,13 @@ static int pci_pm_poweroff_noirq(struct device *dev)
+ if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+
++ /*
++ * The reason for doing this here is the same as for the analogous code
++ * in pci_pm_suspend_noirq().
++ */
++ if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)
++ pci_write_config_word(pci_dev, PCI_COMMAND, 0);
++
+ return 0;
+ }
+
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index b0859d4..ec5b17f 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -86,6 +86,10 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
+ { KE_KEY, 0x8A, { KEY_PROG1 } },
+ { KE_KEY, 0x95, { KEY_MEDIA } },
+ { KE_KEY, 0x99, { KEY_PHONE } },
++ { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */
++ { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */
++ { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */
++ { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */
+ { KE_KEY, 0xb5, { KEY_CALC } },
+ { KE_KEY, 0xc4, { KEY_KBDILLUMUP } },
+ { KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } },
+diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c
+index 30d2072..33471e1 100644
+--- a/drivers/rapidio/devices/tsi721.c
++++ b/drivers/rapidio/devices/tsi721.c
+@@ -439,6 +439,9 @@ static void tsi721_db_dpc(struct work_struct *work)
+ " info %4.4x\n", DBELL_SID(idb.bytes),
+ DBELL_TID(idb.bytes), DBELL_INF(idb.bytes));
+ }
++
++ wr_ptr = ioread32(priv->regs +
++ TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
+ }
+
+ iowrite32(rd_ptr & (IDB_QSIZE - 1),
+@@ -449,6 +452,10 @@ static void tsi721_db_dpc(struct work_struct *work)
+ regval |= TSI721_SR_CHINT_IDBQRCV;
+ iowrite32(regval,
+ priv->regs + TSI721_SR_CHINTE(IDB_QUEUE));
++
++ wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE;
++ if (wr_ptr != rd_ptr)
++ schedule_work(&priv->idb_work);
+ }
+
+ /**
+@@ -2155,7 +2162,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+ {
+ struct tsi721_device *priv;
+- int i, cap;
++ int cap;
+ int err;
+ u32 regval;
+
+@@ -2175,12 +2182,15 @@ static int __devinit tsi721_probe(struct pci_dev *pdev,
+ priv->pdev = pdev;
+
+ #ifdef DEBUG
++ {
++ int i;
+ for (i = 0; i <= PCI_STD_RESOURCE_END; i++) {
+ dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n",
+ i, (unsigned long long)pci_resource_start(pdev, i),
+ (unsigned long)pci_resource_len(pdev, i),
+ pci_resource_flags(pdev, i));
+ }
++ }
+ #endif
+ /*
+ * Verify BAR configuration
+diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
+index 971bc8e..11bcb20 100644
+--- a/drivers/rtc/rtc-rs5c348.c
++++ b/drivers/rtc/rtc-rs5c348.c
+@@ -122,9 +122,12 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
+ tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK);
+ tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK);
+ if (!pdata->rtc_24h) {
+- tm->tm_hour %= 12;
+- if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM)
++ if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) {
++ tm->tm_hour -= 20;
++ tm->tm_hour %= 12;
+ tm->tm_hour += 12;
++ } else
++ tm->tm_hour %= 12;
+ }
+ tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK);
+ tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK);
+diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
+index 8be5604..0d70f68 100644
+--- a/drivers/staging/speakup/main.c
++++ b/drivers/staging/speakup/main.c
+@@ -1854,7 +1854,7 @@ static void speakup_bits(struct vc_data *vc)
+
+ static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key)
+ {
+- static u_char *goto_buf = "\0\0\0\0\0\0";
++ static u_char goto_buf[8];
+ static int num;
+ int maxlen, go_pos;
+ char *cp;
+diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
+index 27521b6..ae62d57 100644
+--- a/drivers/staging/vt6656/main_usb.c
++++ b/drivers/staging/vt6656/main_usb.c
+@@ -222,7 +222,7 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode");
+ // Static vars definitions
+ //
+
+-static struct usb_device_id vt6656_table[] __devinitdata = {
++static struct usb_device_id vt6656_table[] = {
+ {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
+ {}
+ };
+diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
+index f958eb4..3f0ce2b 100644
+--- a/drivers/staging/winbond/wbusb.c
++++ b/drivers/staging/winbond/wbusb.c
+@@ -25,7 +25,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION("0.1");
+
+-static const struct usb_device_id wb35_table[] __devinitconst = {
++static const struct usb_device_id wb35_table[] = {
+ { USB_DEVICE(0x0416, 0x0035) },
+ { USB_DEVICE(0x18E8, 0x6201) },
+ { USB_DEVICE(0x18E8, 0x6206) },
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index 94c03d2..597fb9b 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -3509,9 +3509,9 @@ transport_generic_get_mem(struct se_cmd *cmd)
+ return 0;
+
+ out:
+- while (i >= 0) {
+- __free_page(sg_page(&cmd->t_data_sg[i]));
++ while (i > 0) {
+ i--;
++ __free_page(sg_page(&cmd->t_data_sg[i]));
+ }
+ kfree(cmd->t_data_sg);
+ cmd->t_data_sg = NULL;
+diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
+index 5acd24a..086f7fe 100644
+--- a/drivers/tty/serial/pmac_zilog.c
++++ b/drivers/tty/serial/pmac_zilog.c
+@@ -1407,10 +1407,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser)
+ static int pmz_poll_get_char(struct uart_port *port)
+ {
+ struct uart_pmac_port *uap = (struct uart_pmac_port *)port;
++ int tries = 2;
+
+- while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0)
+- udelay(5);
+- return read_zsdata(uap);
++ while (tries) {
++ if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0)
++ return read_zsdata(uap);
++ if (tries--)
++ udelay(5);
++ }
++
++ return NO_POLL_CHAR;
+ }
+
+ static void pmz_poll_put_char(struct uart_port *port, unsigned char c)
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 1094469..dbf7d20 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1043,7 +1043,8 @@ skip_normal_probe:
+ }
+
+
+- if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
++ if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 ||
++ control_interface->cur_altsetting->desc.bNumEndpoints == 0)
+ return -EINVAL;
+
+ epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
+diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
+index 4e1f0aa..9a2a1ae 100644
+--- a/drivers/usb/gadget/u_ether.c
++++ b/drivers/usb/gadget/u_ether.c
+@@ -669,6 +669,8 @@ static int eth_stop(struct net_device *net)
+ spin_lock_irqsave(&dev->lock, flags);
+ if (dev->port_usb) {
+ struct gether *link = dev->port_usb;
++ const struct usb_endpoint_descriptor *in;
++ const struct usb_endpoint_descriptor *out;
+
+ if (link->close)
+ link->close(link);
+@@ -682,10 +684,14 @@ static int eth_stop(struct net_device *net)
+ * their own pace; the network stack can handle old packets.
+ * For the moment we leave this here, since it works.
+ */
++ in = link->in_ep->desc;
++ out = link->out_ep->desc;
+ usb_ep_disable(link->in_ep);
+ usb_ep_disable(link->out_ep);
+ if (netif_carrier_ok(net)) {
+ DBG(dev, "host still using in/out endpoints\n");
++ link->in_ep->desc = in;
++ link->out_ep->desc = out;
+ usb_ep_enable(link->in_ep);
+ usb_ep_enable(link->out_ep);
+ }
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index daf5754..07c72a4 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -95,6 +95,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
+ xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
++ xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ }
+ if (pdev->vendor == PCI_VENDOR_ID_VIA)
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 05f82e9..f7c0a2a 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -163,7 +163,7 @@ int xhci_reset(struct xhci_hcd *xhci)
+ xhci_writel(xhci, command, &xhci->op_regs->command);
+
+ ret = handshake(xhci, &xhci->op_regs->command,
+- CMD_RESET, 0, 250 * 1000);
++ CMD_RESET, 0, 10 * 1000 * 1000);
+ if (ret)
+ return ret;
+
+@@ -172,7 +172,8 @@ int xhci_reset(struct xhci_hcd *xhci)
+ * xHCI cannot write to any doorbells or operational registers other
+ * than status until the "Controller Not Ready" flag is cleared.
+ */
+- return handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000);
++ return handshake(xhci, &xhci->op_regs->status,
++ STS_CNR, 0, 10 * 1000 * 1000);
+ }
+
+ #ifdef CONFIG_PCI
+diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
+index fc15ad4..723e833 100644
+--- a/drivers/usb/misc/emi62.c
++++ b/drivers/usb/misc/emi62.c
+@@ -259,7 +259,7 @@ wraperr:
+ return err;
+ }
+
+-static const struct usb_device_id id_table[] __devinitconst = {
++static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) },
+ { } /* Terminating entry */
+ };
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 4045e39..b3182bb 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -811,6 +811,7 @@ static struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) },
+ { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) },
+ { USB_DEVICE(PI_VID, PI_E861_PID) },
++ { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) },
+ { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+ { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index d27d7d7..54b4258 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -795,6 +795,13 @@
+ #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */
+
+ /*
++ * Kondo Kagaku Co.Ltd.
++ * http://www.kondo-robot.com/EN
++ */
++#define KONDO_VID 0x165c
++#define KONDO_USB_SERIAL_PID 0x0002
++
++/*
+ * Bayer Ascensia Contour blood glucose meter USB-converter cable.
+ * http://winglucofacts.com/cables/
+ */
+diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
+index 5c7d654..b150ed9 100644
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -1191,9 +1191,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty)
+ }
+
+ spin_lock_irqsave(&mos7840_port->pool_lock, flags);
+- for (i = 0; i < NUM_URBS; ++i)
+- if (mos7840_port->busy[i])
+- chars += URB_TRANSFER_BUFFER_SIZE;
++ for (i = 0; i < NUM_URBS; ++i) {
++ if (mos7840_port->busy[i]) {
++ struct urb *urb = mos7840_port->write_urb_pool[i];
++ chars += urb->transfer_buffer_length;
++ }
++ }
+ spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
+ dbg("%s - returns %d", __func__, chars);
+ return chars;
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index d89aac1..113560d 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -80,84 +80,9 @@ static void option_instat_callback(struct urb *urb);
+ #define OPTION_PRODUCT_GTM380_MODEM 0x7201
+
+ #define HUAWEI_VENDOR_ID 0x12D1
+-#define HUAWEI_PRODUCT_E600 0x1001
+-#define HUAWEI_PRODUCT_E220 0x1003
+-#define HUAWEI_PRODUCT_E220BIS 0x1004
+-#define HUAWEI_PRODUCT_E1401 0x1401
+-#define HUAWEI_PRODUCT_E1402 0x1402
+-#define HUAWEI_PRODUCT_E1403 0x1403
+-#define HUAWEI_PRODUCT_E1404 0x1404
+-#define HUAWEI_PRODUCT_E1405 0x1405
+-#define HUAWEI_PRODUCT_E1406 0x1406
+-#define HUAWEI_PRODUCT_E1407 0x1407
+-#define HUAWEI_PRODUCT_E1408 0x1408
+-#define HUAWEI_PRODUCT_E1409 0x1409
+-#define HUAWEI_PRODUCT_E140A 0x140A
+-#define HUAWEI_PRODUCT_E140B 0x140B
+-#define HUAWEI_PRODUCT_E140C 0x140C
+-#define HUAWEI_PRODUCT_E140D 0x140D
+-#define HUAWEI_PRODUCT_E140E 0x140E
+-#define HUAWEI_PRODUCT_E140F 0x140F
+-#define HUAWEI_PRODUCT_E1410 0x1410
+-#define HUAWEI_PRODUCT_E1411 0x1411
+-#define HUAWEI_PRODUCT_E1412 0x1412
+-#define HUAWEI_PRODUCT_E1413 0x1413
+-#define HUAWEI_PRODUCT_E1414 0x1414
+-#define HUAWEI_PRODUCT_E1415 0x1415
+-#define HUAWEI_PRODUCT_E1416 0x1416
+-#define HUAWEI_PRODUCT_E1417 0x1417
+-#define HUAWEI_PRODUCT_E1418 0x1418
+-#define HUAWEI_PRODUCT_E1419 0x1419
+-#define HUAWEI_PRODUCT_E141A 0x141A
+-#define HUAWEI_PRODUCT_E141B 0x141B
+-#define HUAWEI_PRODUCT_E141C 0x141C
+-#define HUAWEI_PRODUCT_E141D 0x141D
+-#define HUAWEI_PRODUCT_E141E 0x141E
+-#define HUAWEI_PRODUCT_E141F 0x141F
+-#define HUAWEI_PRODUCT_E1420 0x1420
+-#define HUAWEI_PRODUCT_E1421 0x1421
+-#define HUAWEI_PRODUCT_E1422 0x1422
+-#define HUAWEI_PRODUCT_E1423 0x1423
+-#define HUAWEI_PRODUCT_E1424 0x1424
+-#define HUAWEI_PRODUCT_E1425 0x1425
+-#define HUAWEI_PRODUCT_E1426 0x1426
+-#define HUAWEI_PRODUCT_E1427 0x1427
+-#define HUAWEI_PRODUCT_E1428 0x1428
+-#define HUAWEI_PRODUCT_E1429 0x1429
+-#define HUAWEI_PRODUCT_E142A 0x142A
+-#define HUAWEI_PRODUCT_E142B 0x142B
+-#define HUAWEI_PRODUCT_E142C 0x142C
+-#define HUAWEI_PRODUCT_E142D 0x142D
+-#define HUAWEI_PRODUCT_E142E 0x142E
+-#define HUAWEI_PRODUCT_E142F 0x142F
+-#define HUAWEI_PRODUCT_E1430 0x1430
+-#define HUAWEI_PRODUCT_E1431 0x1431
+-#define HUAWEI_PRODUCT_E1432 0x1432
+-#define HUAWEI_PRODUCT_E1433 0x1433
+-#define HUAWEI_PRODUCT_E1434 0x1434
+-#define HUAWEI_PRODUCT_E1435 0x1435
+-#define HUAWEI_PRODUCT_E1436 0x1436
+-#define HUAWEI_PRODUCT_E1437 0x1437
+-#define HUAWEI_PRODUCT_E1438 0x1438
+-#define HUAWEI_PRODUCT_E1439 0x1439
+-#define HUAWEI_PRODUCT_E143A 0x143A
+-#define HUAWEI_PRODUCT_E143B 0x143B
+-#define HUAWEI_PRODUCT_E143C 0x143C
+-#define HUAWEI_PRODUCT_E143D 0x143D
+-#define HUAWEI_PRODUCT_E143E 0x143E
+-#define HUAWEI_PRODUCT_E143F 0x143F
+ #define HUAWEI_PRODUCT_K4505 0x1464
+ #define HUAWEI_PRODUCT_K3765 0x1465
+-#define HUAWEI_PRODUCT_E14AC 0x14AC
+-#define HUAWEI_PRODUCT_K3806 0x14AE
+ #define HUAWEI_PRODUCT_K4605 0x14C6
+-#define HUAWEI_PRODUCT_K3770 0x14C9
+-#define HUAWEI_PRODUCT_K3771 0x14CA
+-#define HUAWEI_PRODUCT_K4510 0x14CB
+-#define HUAWEI_PRODUCT_K4511 0x14CC
+-#define HUAWEI_PRODUCT_ETS1220 0x1803
+-#define HUAWEI_PRODUCT_E353 0x1506
+-#define HUAWEI_PRODUCT_E173S 0x1C05
+
+ #define QUANTA_VENDOR_ID 0x0408
+ #define QUANTA_PRODUCT_Q101 0xEA02
+@@ -614,101 +539,123 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) },
+ { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) },
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */
+- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x03) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x04) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x05) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x06) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0D) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0E) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0F) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x10) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x12) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x13) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x14) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x15) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x17) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x18) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x19) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1C) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x31) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x32) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x33) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x34) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x35) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x36) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3D) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3E) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3F) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x48) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x49) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4C) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x61) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x62) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x63) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x64) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x65) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x66) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7C) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x01) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x02) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x03) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x04) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x05) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x06) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0D) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0E) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0F) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x10) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x12) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x13) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x14) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x15) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x17) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x18) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x19) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1C) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x31) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x32) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x33) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x34) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x35) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x36) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3D) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3E) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3F) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x48) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x49) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4C) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x61) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x62) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x63) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x64) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x65) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x66) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) },
++ { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) },
++
++
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
+diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
+index 8745637..bf9a9b7 100644
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -373,8 +373,15 @@ static void fb_flashcursor(struct work_struct *work)
+ struct vc_data *vc = NULL;
+ int c;
+ int mode;
++ int ret;
++
++ /* FIXME: we should sort out the unbind locking instead */
++ /* instead we just fail to flash the cursor if we can't get
++ * the lock instead of blocking fbcon deinit */
++ ret = console_trylock();
++ if (ret == 0)
++ return;
+
+- console_lock();
+ if (ops && ops->currcon != -1)
+ vc = vc_cons[ops->currcon].d;
+
+diff --git a/fs/buffer.c b/fs/buffer.c
+index 4115eca..19a4f0b 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -964,7 +964,7 @@ link_dev_buffers(struct page *page, struct buffer_head *head)
+ /*
+ * Initialise the state of a blockdev page's buffers.
+ */
+-static void
++static sector_t
+ init_page_buffers(struct page *page, struct block_device *bdev,
+ sector_t block, int size)
+ {
+@@ -986,33 +986,41 @@ init_page_buffers(struct page *page, struct block_device *bdev,
+ block++;
+ bh = bh->b_this_page;
+ } while (bh != head);
++
++ /*
++ * Caller needs to validate requested block against end of device.
++ */
++ return end_block;
+ }
+
+ /*
+ * Create the page-cache page that contains the requested block.
+ *
+- * This is user purely for blockdev mappings.
++ * This is used purely for blockdev mappings.
+ */
+-static struct page *
++static int
+ grow_dev_page(struct block_device *bdev, sector_t block,
+- pgoff_t index, int size)
++ pgoff_t index, int size, int sizebits)
+ {
+ struct inode *inode = bdev->bd_inode;
+ struct page *page;
+ struct buffer_head *bh;
++ sector_t end_block;
++ int ret = 0; /* Will call free_more_memory() */
+
+ page = find_or_create_page(inode->i_mapping, index,
+ (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE);
+ if (!page)
+- return NULL;
++ return ret;
+
+ BUG_ON(!PageLocked(page));
+
+ if (page_has_buffers(page)) {
+ bh = page_buffers(page);
+ if (bh->b_size == size) {
+- init_page_buffers(page, bdev, block, size);
+- return page;
++ end_block = init_page_buffers(page, bdev,
++ index << sizebits, size);
++ goto done;
+ }
+ if (!try_to_free_buffers(page))
+ goto failed;
+@@ -1032,15 +1040,14 @@ grow_dev_page(struct block_device *bdev, sector_t block,
+ */
+ spin_lock(&inode->i_mapping->private_lock);
+ link_dev_buffers(page, bh);
+- init_page_buffers(page, bdev, block, size);
++ end_block = init_page_buffers(page, bdev, index << sizebits, size);
+ spin_unlock(&inode->i_mapping->private_lock);
+- return page;
+-
++done:
++ ret = (block < end_block) ? 1 : -ENXIO;
+ failed:
+- BUG();
+ unlock_page(page);
+ page_cache_release(page);
+- return NULL;
++ return ret;
+ }
+
+ /*
+@@ -1050,7 +1057,6 @@ failed:
+ static int
+ grow_buffers(struct block_device *bdev, sector_t block, int size)
+ {
+- struct page *page;
+ pgoff_t index;
+ int sizebits;
+
+@@ -1074,22 +1080,14 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
+ bdevname(bdev, b));
+ return -EIO;
+ }
+- block = index << sizebits;
++
+ /* Create a page with the proper size buffers.. */
+- page = grow_dev_page(bdev, block, index, size);
+- if (!page)
+- return 0;
+- unlock_page(page);
+- page_cache_release(page);
+- return 1;
++ return grow_dev_page(bdev, block, index, size, sizebits);
+ }
+
+ static struct buffer_head *
+ __getblk_slow(struct block_device *bdev, sector_t block, int size)
+ {
+- int ret;
+- struct buffer_head *bh;
+-
+ /* Size must be multiple of hard sectorsize */
+ if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
+ (size < 512 || size > PAGE_SIZE))) {
+@@ -1102,21 +1100,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
+ return NULL;
+ }
+
+-retry:
+- bh = __find_get_block(bdev, block, size);
+- if (bh)
+- return bh;
++ for (;;) {
++ struct buffer_head *bh;
++ int ret;
+
+- ret = grow_buffers(bdev, block, size);
+- if (ret == 0) {
+- free_more_memory();
+- goto retry;
+- } else if (ret > 0) {
+ bh = __find_get_block(bdev, block, size);
+ if (bh)
+ return bh;
++
++ ret = grow_buffers(bdev, block, size);
++ if (ret < 0)
++ return NULL;
++ if (ret == 0)
++ free_more_memory();
+ }
+- return NULL;
+ }
+
+ /*
+@@ -1372,10 +1369,6 @@ EXPORT_SYMBOL(__find_get_block);
+ * which corresponds to the passed block_device, block and size. The
+ * returned buffer has its reference count incremented.
+ *
+- * __getblk() cannot fail - it just keeps trying. If you pass it an
+- * illegal block number, __getblk() will happily return a buffer_head
+- * which represents the non-existent block. Very weird.
+- *
+ * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers()
+ * attempt is failing. FIXME, perhaps?
+ */
+diff --git a/fs/compat.c b/fs/compat.c
+index c987875..e07a3d3 100644
+--- a/fs/compat.c
++++ b/fs/compat.c
+@@ -1174,11 +1174,14 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
+ struct file *file;
+ int fput_needed;
+ ssize_t ret;
++ loff_t pos;
+
+ file = fget_light(fd, &fput_needed);
+ if (!file)
+ return -EBADF;
+- ret = compat_readv(file, vec, vlen, &file->f_pos);
++ pos = file->f_pos;
++ ret = compat_readv(file, vec, vlen, &pos);
++ file->f_pos = pos;
+ fput_light(file, fput_needed);
+ return ret;
+ }
+@@ -1233,11 +1236,14 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
+ struct file *file;
+ int fput_needed;
+ ssize_t ret;
++ loff_t pos;
+
+ file = fget_light(fd, &fput_needed);
+ if (!file)
+ return -EBADF;
+- ret = compat_writev(file, vec, vlen, &file->f_pos);
++ pos = file->f_pos;
++ ret = compat_writev(file, vec, vlen, &pos);
++ file->f_pos = pos;
+ fput_light(file, fput_needed);
+ return ret;
+ }
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index a071348..f8d5fce 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -904,6 +904,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+ ei->i_reserved_meta_blocks = 0;
+ ei->i_allocated_meta_blocks = 0;
+ ei->i_da_metadata_calc_len = 0;
++ ei->i_da_metadata_calc_last_lblock = 0;
+ spin_lock_init(&(ei->i_block_reservation_lock));
+ #ifdef CONFIG_QUOTA
+ ei->i_reserved_quota = 0;
+@@ -3107,6 +3108,10 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp,
+ ext4_group_t i, ngroups = ext4_get_groups_count(sb);
+ int s, j, count = 0;
+
++ if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC))
++ return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) +
++ sbi->s_itb_per_group + 2);
++
+ first_block = le32_to_cpu(sbi->s_es->s_first_data_block) +
+ (grp * EXT4_BLOCKS_PER_GROUP(sb));
+ last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1;
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 0c84100..5242006 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1687,7 +1687,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
+ size_t n;
+ u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
+
+- for (n = 0; n < count; n++) {
++ for (n = 0; n < count; n++, iov++) {
+ if (iov->iov_len > (size_t) max)
+ return -ENOMEM;
+ max -= iov->iov_len;
+diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
+index 3db6b82..d774309 100644
+--- a/fs/nfs/blocklayout/blocklayout.c
++++ b/fs/nfs/blocklayout/blocklayout.c
+@@ -38,6 +38,8 @@
+ #include <linux/buffer_head.h> /* various write calls */
+ #include <linux/prefetch.h>
+
++#include "../pnfs.h"
++#include "../internal.h"
+ #include "blocklayout.h"
+
+ #define NFSDBG_FACILITY NFSDBG_PNFS_LD
+@@ -814,7 +816,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
+ * GETDEVICEINFO's maxcount
+ */
+ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
+- max_pages = max_resp_sz >> PAGE_SHIFT;
++ max_pages = nfs_page_array_len(0, max_resp_sz);
+ dprintk("%s max_resp_sz %u max_pages %d\n",
+ __func__, max_resp_sz, max_pages);
+
+diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c
+index c69682a..4e2ee99 100644
+--- a/fs/nfs/blocklayout/extents.c
++++ b/fs/nfs/blocklayout/extents.c
+@@ -153,7 +153,7 @@ static int _preload_range(struct pnfs_inval_markings *marks,
+ count = (int)(end - start) / (int)tree->mtt_step_size;
+
+ /* Pre-malloc what memory we might need */
+- storage = kmalloc(sizeof(*storage) * count, GFP_NOFS);
++ storage = kcalloc(count, sizeof(*storage), GFP_NOFS);
+ if (!storage)
+ return -ENOMEM;
+ for (i = 0; i < count; i++) {
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index ac28990..756f4df 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -1103,7 +1103,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
+ struct nfs_fattr *fattr = NULL;
+ int error;
+
+- if (nd->flags & LOOKUP_RCU)
++ if (nd && (nd->flags & LOOKUP_RCU))
+ return -ECHILD;
+
+ parent = dget_parent(dentry);
+@@ -1508,7 +1508,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
+ struct nfs_open_context *ctx;
+ int openflags, ret = 0;
+
+- if (nd->flags & LOOKUP_RCU)
++ if (nd && (nd->flags & LOOKUP_RCU))
+ return -ECHILD;
+
+ inode = dentry->d_inode;
+diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
+index d4bc9ed9..5195fd6 100644
+--- a/fs/nfs/nfs3proc.c
++++ b/fs/nfs/nfs3proc.c
+@@ -68,7 +68,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
+ nfs_fattr_init(info->fattr);
+ status = rpc_call_sync(client, &msg, 0);
+ dprintk("%s: reply fsinfo: %d\n", __func__, status);
+- if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
++ if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) {
+ msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
+ msg.rpc_resp = info->fattr;
+ status = rpc_call_sync(client, &msg, 0);
+diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
+index ed388aa..bd5d9cf 100644
+--- a/fs/nfs/nfs4filelayoutdev.c
++++ b/fs/nfs/nfs4filelayoutdev.c
+@@ -721,7 +721,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla
+ * GETDEVICEINFO's maxcount
+ */
+ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
+- max_pages = max_resp_sz >> PAGE_SHIFT;
++ max_pages = nfs_page_array_len(0, max_resp_sz);
+ dprintk("%s inode %p max_resp_sz %u max_pages %d\n",
+ __func__, inode, max_resp_sz, max_pages);
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 8000459..d20221d 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -5769,11 +5769,58 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
+ dprintk("<-- %s\n", __func__);
+ }
+
++static size_t max_response_pages(struct nfs_server *server)
++{
++ u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
++ return nfs_page_array_len(0, max_resp_sz);
++}
++
++static void nfs4_free_pages(struct page **pages, size_t size)
++{
++ int i;
++
++ if (!pages)
++ return;
++
++ for (i = 0; i < size; i++) {
++ if (!pages[i])
++ break;
++ __free_page(pages[i]);
++ }
++ kfree(pages);
++}
++
++static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags)
++{
++ struct page **pages;
++ int i;
++
++ pages = kcalloc(size, sizeof(struct page *), gfp_flags);
++ if (!pages) {
++ dprintk("%s: can't alloc array of %zu pages\n", __func__, size);
++ return NULL;
++ }
++
++ for (i = 0; i < size; i++) {
++ pages[i] = alloc_page(gfp_flags);
++ if (!pages[i]) {
++ dprintk("%s: failed to allocate page\n", __func__);
++ nfs4_free_pages(pages, size);
++ return NULL;
++ }
++ }
++
++ return pages;
++}
++
+ static void nfs4_layoutget_release(void *calldata)
+ {
+ struct nfs4_layoutget *lgp = calldata;
++ struct nfs_server *server = NFS_SERVER(lgp->args.inode);
++ size_t max_pages = max_response_pages(server);
+
+ dprintk("--> %s\n", __func__);
++ nfs4_free_pages(lgp->args.layout.pages, max_pages);
+ put_nfs_open_context(lgp->args.ctx);
+ kfree(calldata);
+ dprintk("<-- %s\n", __func__);
+@@ -5785,9 +5832,10 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = {
+ .rpc_release = nfs4_layoutget_release,
+ };
+
+-int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
++int nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
+ {
+ struct nfs_server *server = NFS_SERVER(lgp->args.inode);
++ size_t max_pages = max_response_pages(server);
+ struct rpc_task *task;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET],
+@@ -5805,6 +5853,13 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
+
+ dprintk("--> %s\n", __func__);
+
++ lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
++ if (!lgp->args.layout.pages) {
++ nfs4_layoutget_release(lgp);
++ return -ENOMEM;
++ }
++ lgp->args.layout.pglen = max_pages * PAGE_SIZE;
++
+ lgp->res.layoutp = &lgp->args.layout;
+ lgp->res.seq_res.sr_slot = NULL;
+ task = rpc_run_task(&task_setup_data);
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index f881a63..3ad6595 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -575,9 +575,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
+ struct nfs_server *server = NFS_SERVER(ino);
+ struct nfs4_layoutget *lgp;
+ struct pnfs_layout_segment *lseg = NULL;
+- struct page **pages = NULL;
+- int i;
+- u32 max_resp_sz, max_pages;
+
+ dprintk("--> %s\n", __func__);
+
+@@ -586,20 +583,6 @@ send_layoutget(struct pnfs_layout_hdr *lo,
+ if (lgp == NULL)
+ return NULL;
+
+- /* allocate pages for xdr post processing */
+- max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
+- max_pages = max_resp_sz >> PAGE_SHIFT;
+-
+- pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags);
+- if (!pages)
+- goto out_err_free;
+-
+- for (i = 0; i < max_pages; i++) {
+- pages[i] = alloc_page(gfp_flags);
+- if (!pages[i])
+- goto out_err_free;
+- }
+-
+ lgp->args.minlength = PAGE_CACHE_SIZE;
+ if (lgp->args.minlength > range->length)
+ lgp->args.minlength = range->length;
+@@ -608,39 +591,19 @@ send_layoutget(struct pnfs_layout_hdr *lo,
+ lgp->args.type = server->pnfs_curr_ld->id;
+ lgp->args.inode = ino;
+ lgp->args.ctx = get_nfs_open_context(ctx);
+- lgp->args.layout.pages = pages;
+- lgp->args.layout.pglen = max_pages * PAGE_SIZE;
+ lgp->lsegpp = &lseg;
+ lgp->gfp_flags = gfp_flags;
+
+ /* Synchronously retrieve layout information from server and
+ * store in lseg.
+ */
+- nfs4_proc_layoutget(lgp);
++ nfs4_proc_layoutget(lgp, gfp_flags);
+ if (!lseg) {
+ /* remember that LAYOUTGET failed and suspend trying */
+ set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
+ }
+
+- /* free xdr pages */
+- for (i = 0; i < max_pages; i++)
+- __free_page(pages[i]);
+- kfree(pages);
+-
+ return lseg;
+-
+-out_err_free:
+- /* free any allocated xdr pages, lgp as it's not used */
+- if (pages) {
+- for (i = 0; i < max_pages; i++) {
+- if (!pages[i])
+- break;
+- __free_page(pages[i]);
+- }
+- kfree(pages);
+- }
+- kfree(lgp);
+- return NULL;
+ }
+
+ /* Initiates a LAYOUTRETURN(FILE) */
+diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
+index 53d593a..c946b1b 100644
+--- a/fs/nfs/pnfs.h
++++ b/fs/nfs/pnfs.h
+@@ -162,7 +162,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server,
+ struct pnfs_devicelist *devlist);
+ extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
+ struct pnfs_device *dev);
+-extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
++extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
+ extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
+
+ /* pnfs.c */
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 376cd65..6e85ec6 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -3087,4 +3087,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
+ return res;
+ }
+
++MODULE_ALIAS("nfs4");
++
+ #endif /* CONFIG_NFS_V4 */
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index c6e523a..301391a 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1742,12 +1742,12 @@ int __init nfs_init_writepagecache(void)
+ nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE,
+ nfs_wdata_cachep);
+ if (nfs_wdata_mempool == NULL)
+- return -ENOMEM;
++ goto out_destroy_write_cache;
+
+ nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT,
+ nfs_wdata_cachep);
+ if (nfs_commit_mempool == NULL)
+- return -ENOMEM;
++ goto out_destroy_write_mempool;
+
+ /*
+ * NFS congestion size, scale with available memory.
+@@ -1770,6 +1770,12 @@ int __init nfs_init_writepagecache(void)
+ nfs_congestion_kb = 256*1024;
+
+ return 0;
++
++out_destroy_write_mempool:
++ mempool_destroy(nfs_wdata_mempool);
++out_destroy_write_cache:
++ kmem_cache_destroy(nfs_wdata_cachep);
++ return -ENOMEM;
+ }
+
+ void nfs_destroy_writepagecache(void)
+diff --git a/fs/open.c b/fs/open.c
+index e2b5d51..b8485d3 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -882,9 +882,10 @@ static inline int build_open_flags(int flags, int mode, struct open_flags *op)
+ int lookup_flags = 0;
+ int acc_mode;
+
+- if (!(flags & O_CREAT))
+- mode = 0;
+- op->mode = mode;
++ if (flags & O_CREAT)
++ op->mode = (mode & S_IALLUGO) | S_IFREG;
++ else
++ op->mode = 0;
+
+ /* Must never be set by userspace */
+ flags &= ~FMODE_NONOTIFY;
+diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
+index 2da1715..4619247 100644
+--- a/fs/squashfs/super.c
++++ b/fs/squashfs/super.c
+@@ -290,7 +290,7 @@ handle_fragments:
+
+ check_directory_table:
+ /* Sanity check directory_table */
+- if (msblk->directory_table >= next_table) {
++ if (msblk->directory_table > next_table) {
+ err = -EINVAL;
+ goto failed_mount;
+ }
+diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h
+index 580a6d3..c04e0db 100644
+--- a/include/asm-generic/mutex-xchg.h
++++ b/include/asm-generic/mutex-xchg.h
+@@ -26,7 +26,13 @@ static inline void
+ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+ {
+ if (unlikely(atomic_xchg(count, 0) != 1))
+- fail_fn(count);
++ /*
++ * We failed to acquire the lock, so mark it contended
++ * to ensure that any waiting tasks are woken up by the
++ * unlock slow path.
++ */
++ if (likely(atomic_xchg(count, -1) != 1))
++ fail_fn(count);
+ }
+
+ /**
+@@ -43,7 +49,8 @@ static inline int
+ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+ {
+ if (unlikely(atomic_xchg(count, 0) != 1))
+- return fail_fn(count);
++ if (likely(atomic_xchg(count, -1) != 1))
++ return fail_fn(count);
+ return 0;
+ }
+
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 4269c3f..93629fc 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -775,6 +775,27 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
+ .bInterfaceSubClass = (sc), \
+ .bInterfaceProtocol = (pr)
+
++/**
++ * USB_VENDOR_AND_INTERFACE_INFO - describe a specific usb vendor with a class of usb interfaces
++ * @vend: the 16 bit USB Vendor ID
++ * @cl: bInterfaceClass value
++ * @sc: bInterfaceSubClass value
++ * @pr: bInterfaceProtocol value
++ *
++ * This macro is used to create a struct usb_device_id that matches a
++ * specific vendor with a specific class of interfaces.
++ *
++ * This is especially useful when explicitly matching devices that have
++ * vendor specific bDeviceClass values, but standards-compliant interfaces.
++ */
++#define USB_VENDOR_AND_INTERFACE_INFO(vend, cl, sc, pr) \
++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
++ | USB_DEVICE_ID_MATCH_VENDOR, \
++ .idVendor = (vend), \
++ .bInterfaceClass = (cl), \
++ .bInterfaceSubClass = (sc), \
++ .bInterfaceProtocol = (pr)
++
+ /* ----------------------------------------------------------------------- */
+
+ /* Stuff for dynamic usb ids */
+diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
+index 5bf0790..31fdc48 100644
+--- a/kernel/audit_tree.c
++++ b/kernel/audit_tree.c
+@@ -250,7 +250,6 @@ static void untag_chunk(struct node *p)
+ spin_unlock(&hash_lock);
+ spin_unlock(&entry->lock);
+ fsnotify_destroy_mark(entry);
+- fsnotify_put_mark(entry);
+ goto out;
+ }
+
+@@ -259,7 +258,7 @@ static void untag_chunk(struct node *p)
+
+ fsnotify_duplicate_mark(&new->mark, entry);
+ if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) {
+- free_chunk(new);
++ fsnotify_put_mark(&new->mark);
+ goto Fallback;
+ }
+
+@@ -293,7 +292,6 @@ static void untag_chunk(struct node *p)
+ spin_unlock(&hash_lock);
+ spin_unlock(&entry->lock);
+ fsnotify_destroy_mark(entry);
+- fsnotify_put_mark(entry);
+ goto out;
+
+ Fallback:
+@@ -322,7 +320,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
+
+ entry = &chunk->mark;
+ if (fsnotify_add_mark(entry, audit_tree_group, inode, NULL, 0)) {
+- free_chunk(chunk);
++ fsnotify_put_mark(entry);
+ return -ENOSPC;
+ }
+
+@@ -332,6 +330,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree)
+ spin_unlock(&hash_lock);
+ chunk->dead = 1;
+ spin_unlock(&entry->lock);
++ fsnotify_get_mark(entry);
+ fsnotify_destroy_mark(entry);
+ fsnotify_put_mark(entry);
+ return 0;
+@@ -396,7 +395,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+ fsnotify_duplicate_mark(chunk_entry, old_entry);
+ if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) {
+ spin_unlock(&old_entry->lock);
+- free_chunk(chunk);
++ fsnotify_put_mark(chunk_entry);
+ fsnotify_put_mark(old_entry);
+ return -ENOSPC;
+ }
+@@ -412,6 +411,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+ spin_unlock(&chunk_entry->lock);
+ spin_unlock(&old_entry->lock);
+
++ fsnotify_get_mark(chunk_entry);
+ fsnotify_destroy_mark(chunk_entry);
+
+ fsnotify_put_mark(chunk_entry);
+@@ -445,7 +445,6 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+ spin_unlock(&old_entry->lock);
+ fsnotify_destroy_mark(old_entry);
+ fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
+- fsnotify_put_mark(old_entry); /* and kill it */
+ return 0;
+ }
+
+diff --git a/kernel/sched.c b/kernel/sched.c
+index e0431c4..910db7d 100644
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -4355,6 +4355,20 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+ # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs)
+ #endif
+
++static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total)
++{
++ u64 temp = (__force u64) rtime;
++
++ temp *= (__force u64) utime;
++
++ if (sizeof(cputime_t) == 4)
++ temp = div_u64(temp, (__force u32) total);
++ else
++ temp = div64_u64(temp, (__force u64) total);
++
++ return (__force cputime_t) temp;
++}
++
+ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+ {
+ cputime_t rtime, utime = p->utime, total = cputime_add(utime, p->stime);
+@@ -4364,13 +4378,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+ */
+ rtime = nsecs_to_cputime(p->se.sum_exec_runtime);
+
+- if (total) {
+- u64 temp = rtime;
+-
+- temp *= utime;
+- do_div(temp, total);
+- utime = (cputime_t)temp;
+- } else
++ if (total)
++ utime = scale_utime(utime, rtime, total);
++ else
+ utime = rtime;
+
+ /*
+@@ -4397,13 +4407,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st)
+ total = cputime_add(cputime.utime, cputime.stime);
+ rtime = nsecs_to_cputime(cputime.sum_exec_runtime);
+
+- if (total) {
+- u64 temp = rtime;
+-
+- temp *= cputime.utime;
+- do_div(temp, total);
+- utime = (cputime_t)temp;
+- } else
++ if (total)
++ utime = scale_utime(cputime.utime, rtime, total);
++ else
+ utime = rtime;
+
+ sig->prev_utime = max(sig->prev_utime, utime);
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 48febd7..86eb848 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -1977,10 +1977,10 @@ static void get_scan_count(struct zone *zone, struct scan_control *sc,
+ * proportional to the fraction of recently scanned pages on
+ * each list that were recently referenced and in active use.
+ */
+- ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1);
++ ap = anon_prio * (reclaim_stat->recent_scanned[0] + 1);
+ ap /= reclaim_stat->recent_rotated[0] + 1;
+
+- fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1);
++ fp = file_prio * (reclaim_stat->recent_scanned[1] + 1);
+ fp /= reclaim_stat->recent_rotated[1] + 1;
+ spin_unlock_irq(&zone->lru_lock);
+
+@@ -1993,7 +1993,7 @@ out:
+ unsigned long scan;
+
+ scan = zone_nr_lru_pages(zone, sc, l);
+- if (priority || noswap) {
++ if (priority || noswap || !vmscan_swappiness(sc)) {
+ scan >>= priority;
+ if (!scan && force_scan)
+ scan = SWAP_CLUSTER_MAX;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 643a41b..6033f02 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -1411,7 +1411,13 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
+ if (conn->type == ACL_LINK) {
+ conn->state = BT_CONFIG;
+ hci_conn_hold(conn);
+- conn->disc_timeout = HCI_DISCONN_TIMEOUT;
++
++ if (!conn->out &&
++ !(conn->ssp_mode && conn->hdev->ssp_mode) &&
++ !hci_find_link_key(hdev, &ev->bdaddr))
++ conn->disc_timeout = HCI_PAIRING_TIMEOUT;
++ else
++ conn->disc_timeout = HCI_DISCONN_TIMEOUT;
+ mgmt_connected(hdev->id, &ev->bdaddr, conn->type);
+ } else
+ conn->state = BT_CONNECTED;
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 17b5b1c..dd76177 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -862,6 +862,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
+ write_lock_bh(&conn->chan_lock);
+
+ hci_conn_hold(conn->hcon);
++ conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
+
+ bacpy(&bt_sk(sk)->src, conn->src);
+ bacpy(&bt_sk(sk)->dst, conn->dst);
+@@ -2263,12 +2264,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
+ while (len >= L2CAP_CONF_OPT_SIZE) {
+ len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
+
+- switch (type) {
+- case L2CAP_CONF_RFC:
+- if (olen == sizeof(rfc))
+- memcpy(&rfc, (void *)val, olen);
+- goto done;
+- }
++ if (type != L2CAP_CONF_RFC)
++ continue;
++
++ if (olen != sizeof(rfc))
++ break;
++
++ memcpy(&rfc, (void *)val, olen);
++ goto done;
+ }
+
+ /* Use sane default values in case a misbehaving remote device
+diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
+index 75c3582..fb85d37 100644
+--- a/net/dccp/ccid.h
++++ b/net/dccp/ccid.h
+@@ -246,7 +246,7 @@ static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk,
+ u32 __user *optval, int __user *optlen)
+ {
+ int rc = -ENOPROTOOPT;
+- if (ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL)
++ if (ccid != NULL && ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL)
+ rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len,
+ optval, optlen);
+ return rc;
+@@ -257,7 +257,7 @@ static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk,
+ u32 __user *optval, int __user *optlen)
+ {
+ int rc = -ENOPROTOOPT;
+- if (ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL)
++ if (ccid != NULL && ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL)
+ rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len,
+ optval, optlen);
+ return rc;
+diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index 9ed2cd0..3282453 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -315,7 +315,6 @@ static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)
+ */
+ void svc_xprt_enqueue(struct svc_xprt *xprt)
+ {
+- struct svc_serv *serv = xprt->xpt_server;
+ struct svc_pool *pool;
+ struct svc_rqst *rqstp;
+ int cpu;
+@@ -361,8 +360,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
+ rqstp, rqstp->rq_xprt);
+ rqstp->rq_xprt = xprt;
+ svc_xprt_get(xprt);
+- rqstp->rq_reserved = serv->sv_max_mesg;
+- atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
+ pool->sp_stats.threads_woken++;
+ wake_up(&rqstp->rq_wait);
+ } else {
+@@ -642,8 +639,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
+ if (xprt) {
+ rqstp->rq_xprt = xprt;
+ svc_xprt_get(xprt);
+- rqstp->rq_reserved = serv->sv_max_mesg;
+- atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
+
+ /* As there is a shortage of threads and this request
+ * had to be queued, don't allow the thread to wait so
+@@ -740,6 +735,8 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
+ else
+ len = xprt->xpt_ops->xpo_recvfrom(rqstp);
+ dprintk("svc: got len=%d\n", len);
++ rqstp->rq_reserved = serv->sv_max_mesg;
++ atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
+ }
+ svc_xprt_received(xprt);
+
+@@ -796,7 +793,8 @@ int svc_send(struct svc_rqst *rqstp)
+
+ /* Grab mutex to serialize outgoing data. */
+ mutex_lock(&xprt->xpt_mutex);
+- if (test_bit(XPT_DEAD, &xprt->xpt_flags))
++ if (test_bit(XPT_DEAD, &xprt->xpt_flags)
++ || test_bit(XPT_CLOSE, &xprt->xpt_flags))
+ len = -ENOTCONN;
+ else
+ len = xprt->xpt_ops->xpo_sendto(rqstp);
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index 71bed1c..296192c 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -1136,9 +1136,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
+ if (len >= 0)
+ svsk->sk_tcplen += len;
+ if (len != want) {
++ svc_tcp_save_pages(svsk, rqstp);
+ if (len < 0 && len != -EAGAIN)
+ goto err_other;
+- svc_tcp_save_pages(svsk, rqstp);
+ dprintk("svc: incomplete TCP record (%d of %d)\n",
+ svsk->sk_tcplen, svsk->sk_reclen);
+ goto err_noclose;
+diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
+index 254ab52..2210b83 100644
+--- a/sound/pci/hda/hda_proc.c
++++ b/sound/pci/hda/hda_proc.c
+@@ -412,7 +412,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
+ if (digi1 & AC_DIG1_EMPHASIS)
+ snd_iprintf(buffer, " Preemphasis");
+ if (digi1 & AC_DIG1_COPYRIGHT)
+- snd_iprintf(buffer, " Copyright");
++ snd_iprintf(buffer, " Non-Copyright");
+ if (digi1 & AC_DIG1_NONAUDIO)
+ snd_iprintf(buffer, " Non-Audio");
+ if (digi1 & AC_DIG1_PROFESSIONAL)
+diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
+index 35abe3c..b22989e 100644
+--- a/sound/pci/hda/patch_ca0132.c
++++ b/sound/pci/hda/patch_ca0132.c
+@@ -276,6 +276,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
+ int type = dir ? HDA_INPUT : HDA_OUTPUT;
+ struct snd_kcontrol_new knew =
+ HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
++ if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) {
++ snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid);
++ return 0;
++ }
+ sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
+ return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
+ }
+@@ -287,6 +291,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
+ int type = dir ? HDA_INPUT : HDA_OUTPUT;
+ struct snd_kcontrol_new knew =
+ HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
++ if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) {
++ snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid);
++ return 0;
++ }
+ sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
+ return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
+ }
+diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
+index 90117f8..90e5005 100644
+--- a/sound/soc/codecs/wm9712.c
++++ b/sound/soc/codecs/wm9712.c
+@@ -270,7 +270,7 @@ SOC_DAPM_ENUM("Route", wm9712_enum[9]);
+
+ /* Mic select */
+ static const struct snd_kcontrol_new wm9712_mic_src_controls =
+-SOC_DAPM_ENUM("Route", wm9712_enum[7]);
++SOC_DAPM_ENUM("Mic Source Select", wm9712_enum[7]);
+
+ /* diff select */
+ static const struct snd_kcontrol_new wm9712_diff_sel_controls =
+@@ -289,7 +289,9 @@ SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
+ &wm9712_capture_selectl_controls),
+ SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
+ &wm9712_capture_selectr_controls),
+-SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0,
++SND_SOC_DAPM_MUX("Left Mic Select Source", SND_SOC_NOPM, 0, 0,
++ &wm9712_mic_src_controls),
++SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0,
+ &wm9712_mic_src_controls),
+ SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0,
+ &wm9712_diff_sel_controls),
+@@ -317,6 +319,7 @@ SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0),
+ SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Differential Mic", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1),
+ SND_SOC_DAPM_OUTPUT("MONOOUT"),
+ SND_SOC_DAPM_OUTPUT("HPOUTL"),
+@@ -377,6 +380,18 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = {
+ {"Mic PGA", NULL, "MIC1"},
+ {"Mic PGA", NULL, "MIC2"},
+
++ /* microphones */
++ {"Differential Mic", NULL, "MIC1"},
++ {"Differential Mic", NULL, "MIC2"},
++ {"Left Mic Select Source", "Mic 1", "MIC1"},
++ {"Left Mic Select Source", "Mic 2", "MIC2"},
++ {"Left Mic Select Source", "Stereo", "MIC1"},
++ {"Left Mic Select Source", "Differential", "Differential Mic"},
++ {"Right Mic Select Source", "Mic 1", "MIC1"},
++ {"Right Mic Select Source", "Mic 2", "MIC2"},
++ {"Right Mic Select Source", "Stereo", "MIC2"},
++ {"Right Mic Select Source", "Differential", "Differential Mic"},
++
+ /* left capture selector */
+ {"Left Capture Select", "Mic", "MIC1"},
+ {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"},