diff options
Diffstat (limited to '3.2.53/1028_linux-3.2.29.patch')
-rw-r--r-- | 3.2.53/1028_linux-3.2.29.patch | 4279 |
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"}, |