diff options
Diffstat (limited to 'drivers')
30 files changed, 432 insertions, 103 deletions
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 3784a47865b..8f5aebfb29d 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -190,7 +190,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, for (try = 0; try < 5; try++) { new = allocate ? old - bandwidth : old + bandwidth; if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL) - break; + return -EBUSY; data[0] = cpu_to_be32(old); data[1] = cpu_to_be32(new); @@ -218,7 +218,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) { __be32 c, all, old; - int i, retry = 5; + int i, ret = -EIO, retry = 5; old = all = allocate ? cpu_to_be32(~0) : 0; @@ -226,6 +226,8 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, if (!(channels_mask & 1 << i)) continue; + ret = -EBUSY; + c = cpu_to_be32(1 << (31 - i)); if ((old & c) != (all & c)) continue; @@ -251,12 +253,16 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, /* 1394-1995 IRM, fall through to retry. */ default: - if (retry--) + if (retry) { + retry--; i--; + } else { + ret = -EIO; + } } } - return -EIO; + return ret; } static void deallocate_channel(struct fw_card *card, int irm_id, diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 0cf4d7f562c..94b16e0340a 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1158,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr) { struct fw_packet response; - int tcode, length, ext_tcode, sel; + int tcode, length, ext_tcode, sel, try; __be32 *payload, lock_old; u32 lock_arg, lock_data; @@ -1185,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci, reg_write(ohci, OHCI1394_CSRCompareData, lock_arg); reg_write(ohci, OHCI1394_CSRControl, sel); - if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) - lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData)); - else - fw_notify("swap not done yet\n"); + for (try = 0; try < 20; try++) + if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) { + lock_old = cpu_to_be32(reg_read(ohci, + OHCI1394_CSRData)); + fw_fill_response(&response, packet->header, + RCODE_COMPLETE, + &lock_old, sizeof(lock_old)); + goto out; + } + + fw_error("swap not done (CSR lock timeout)\n"); + fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0); - fw_fill_response(&response, packet->header, - RCODE_COMPLETE, &lock_old, sizeof(lock_old)); out: fw_core_handle_response(&ohci->card, &response); } static void handle_local_request(struct context *ctx, struct fw_packet *packet) { - u64 offset; - u32 csr; + u64 offset, csr; if (ctx == &ctx->ohci->at_request_ctx) { packet->ack = ACK_PENDING; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2dc93939507..c3cfafcbfe7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1357,6 +1357,8 @@ static void i915_setup_compression(struct drm_device *dev, int size) dev_priv->cfb_size = size; + dev_priv->compressed_fb = compressed_fb; + if (IS_GM45(dev)) { g4x_disable_fbc(dev); I915_WRITE(DPFC_CB_BASE, compressed_fb->start); @@ -1364,12 +1366,22 @@ static void i915_setup_compression(struct drm_device *dev, int size) i8xx_disable_fbc(dev); I915_WRITE(FBC_CFB_BASE, cfb_base); I915_WRITE(FBC_LL_BASE, ll_base); + dev_priv->compressed_llb = compressed_llb; } DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, ll_base, size >> 20); } +static void i915_cleanup_compression(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + drm_mm_put_block(dev_priv->compressed_fb); + if (!IS_GM45(dev)) + drm_mm_put_block(dev_priv->compressed_llb); +} + /* true = enable decode, false = disable decoder */ static unsigned int i915_vga_set_decode(void *cookie, bool state) { @@ -1787,6 +1799,8 @@ int i915_driver_unload(struct drm_device *dev) mutex_lock(&dev->struct_mutex); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); + if (I915_HAS_FBC(dev) && i915_powersave) + i915_cleanup_compression(dev); drm_mm_takedown(&dev_priv->vram); i915_gem_lastclose(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0af3dcc85ce..cc03537bb88 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -69,7 +69,8 @@ const static struct intel_device_info intel_845g_info = { }; const static struct intel_device_info intel_i85x_info = { - .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, + .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, + .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i865g_info = { @@ -151,7 +152,7 @@ const static struct pci_device_id pciidlist[] = { INTEL_VGA_DEVICE(0x3577, &intel_i830_info), INTEL_VGA_DEVICE(0x2562, &intel_845g_info), INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), - INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info), + INTEL_VGA_DEVICE(0x358e, &intel_i85x_info), INTEL_VGA_DEVICE(0x2572, &intel_i865g_info), INTEL_VGA_DEVICE(0x2582, &intel_i915g_info), INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6960849522f..6e4790065d9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -195,6 +195,7 @@ struct intel_overlay; struct intel_device_info { u8 is_mobile : 1; u8 is_i8xx : 1; + u8 is_i85x : 1; u8 is_i915g : 1; u8 is_i9xx : 1; u8 is_i945gm : 1; @@ -235,11 +236,14 @@ typedef struct drm_i915_private { drm_dma_handle_t *status_page_dmah; void *hw_status_page; + void *seqno_page; dma_addr_t dma_status_page; uint32_t counter; unsigned int status_gfx_addr; + unsigned int seqno_gfx_addr; drm_local_map_t hws_map; struct drm_gem_object *hws_obj; + struct drm_gem_object *seqno_obj; struct drm_gem_object *pwrctx; struct resource mch_res; @@ -630,6 +634,9 @@ typedef struct drm_i915_private { u8 max_delay; enum no_fbc_reason no_fbc_reason; + + struct drm_mm_node *compressed_fb; + struct drm_mm_node *compressed_llb; } drm_i915_private_t; /** driver private structure attached to each drm_gem_object */ @@ -1070,7 +1077,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define IS_I830(dev) ((dev)->pci_device == 0x3577) #define IS_845G(dev) ((dev)->pci_device == 0x2562) -#define IS_I85X(dev) ((dev)->pci_device == 0x3582) +#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) #define IS_I865G(dev) ((dev)->pci_device == 0x2572) #define IS_GEN2(dev) (INTEL_INFO(dev)->is_i8xx) #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) @@ -1135,6 +1142,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) || \ IS_GEN6(dev)) +#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 80871c62a57..7f52cc124cf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1588,6 +1588,13 @@ i915_gem_process_flushing_list(struct drm_device *dev, } } +#define PIPE_CONTROL_FLUSH(addr) \ + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ + PIPE_CONTROL_DEPTH_STALL); \ + OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ + OUT_RING(0); \ + OUT_RING(0); \ + /** * Creates a new sequence number, emitting a write of it to the status page * plus an interrupt, which will trigger i915_user_interrupt_handler. @@ -1622,13 +1629,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, if (dev_priv->mm.next_gem_seqno == 0) dev_priv->mm.next_gem_seqno++; - BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(seqno); + if (HAS_PIPE_CONTROL(dev)) { + u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; - OUT_RING(MI_USER_INTERRUPT); - ADVANCE_LP_RING(); + /* + * Workaround qword write incoherence by flushing the + * PIPE_NOTIFY buffers out to memory before requesting + * an interrupt. + */ + BEGIN_LP_RING(32); + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + OUT_RING(seqno); + OUT_RING(0); + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; /* write to separate cachelines */ + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(scratch_addr); + OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_NOTIFY); + OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + OUT_RING(seqno); + OUT_RING(0); + ADVANCE_LP_RING(); + } else { + BEGIN_LP_RING(4); + OUT_RING(MI_STORE_DWORD_INDEX); + OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(seqno); + + OUT_RING(MI_USER_INTERRUPT); + ADVANCE_LP_RING(); + } DRM_DEBUG_DRIVER("%d\n", seqno); @@ -1752,7 +1793,10 @@ i915_get_gem_seqno(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); + if (IS_I965G(dev)) + return ((volatile u32 *)(dev_priv->seqno_page))[0]; + else + return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); } /** @@ -2362,6 +2406,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) pitch_val = obj_priv->stride / tile_width; pitch_val = ffs(pitch_val) - 1; + if (obj_priv->tiling_mode == I915_TILING_Y && + HAS_128_BYTE_Y_TILING(dev)) + WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); + else + WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); + val = obj_priv->gtt_offset; if (obj_priv->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; @@ -4546,6 +4596,49 @@ i915_gem_idle(struct drm_device *dev) return 0; } +/* + * 965+ support PIPE_CONTROL commands, which provide finer grained control + * over cache flushing. + */ +static int +i915_gem_init_pipe_control(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + int ret; + + obj = drm_gem_object_alloc(dev, 4096); + if (obj == NULL) { + DRM_ERROR("Failed to allocate seqno page\n"); + ret = -ENOMEM; + goto err; + } + obj_priv = to_intel_bo(obj); + obj_priv->agp_type = AGP_USER_CACHED_MEMORY; + + ret = i915_gem_object_pin(obj, 4096); + if (ret) + goto err_unref; + + dev_priv->seqno_gfx_addr = obj_priv->gtt_offset; + dev_priv->seqno_page = kmap(obj_priv->pages[0]); + if (dev_priv->seqno_page == NULL) + goto err_unpin; + + dev_priv->seqno_obj = obj; + memset(dev_priv->seqno_page, 0, PAGE_SIZE); + + return 0; + +err_unpin: + i915_gem_object_unpin(obj); +err_unref: + drm_gem_object_unreference(obj); +err: + return ret; +} + static int i915_gem_init_hws(struct drm_device *dev) { @@ -4563,7 +4656,8 @@ i915_gem_init_hws(struct drm_device *dev) obj = drm_gem_object_alloc(dev, 4096); if (obj == NULL) { DRM_ERROR("Failed to allocate status page\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err; } obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; @@ -4571,7 +4665,7 @@ i915_gem_init_hws(struct drm_device *dev) ret = i915_gem_object_pin(obj, 4096); if (ret != 0) { drm_gem_object_unreference(obj); - return ret; + goto err_unref; } dev_priv->status_gfx_addr = obj_priv->gtt_offset; @@ -4580,10 +4674,16 @@ i915_gem_init_hws(struct drm_device *dev) if (dev_priv->hw_status_page == NULL) { DRM_ERROR("Failed to map status page.\n"); memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); - return -EINVAL; + ret = -EINVAL; + goto err_unpin; } + + if (HAS_PIPE_CONTROL(dev)) { + ret = i915_gem_init_pipe_control(dev); + if (ret) + goto err_unpin; + } + dev_priv->hws_obj = obj; memset(dev_priv->hw_status_page, 0, PAGE_SIZE); if (IS_GEN6(dev)) { @@ -4596,6 +4696,30 @@ i915_gem_init_hws(struct drm_device *dev) DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); return 0; + +err_unpin: + i915_gem_object_unpin(obj); +err_unref: + drm_gem_object_unreference(obj); +err: + return 0; +} + +static void +i915_gem_cleanup_pipe_control(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + + obj = dev_priv->seqno_obj; + obj_priv = to_intel_bo(obj); + kunmap(obj_priv->pages[0]); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(obj); + dev_priv->seqno_obj = NULL; + + dev_priv->seqno_page = NULL; } static void @@ -4619,6 +4743,9 @@ i915_gem_cleanup_hws(struct drm_device *dev) memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); dev_priv->hw_status_page = NULL; + if (HAS_PIPE_CONTROL(dev)) + i915_gem_cleanup_pipe_control(dev); + /* Write high address into HWS_PGA when disabling. */ I915_WRITE(HWS_PGA, 0x1ffff000); } diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 449157f7161..4bdccefcf2c 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) * reg, so dont bother to check the size */ if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) return false; - } else if (IS_I9XX(dev)) { - uint32_t pitch_val = ffs(stride / tile_width) - 1; - - /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB) - * instead of 4 (2KB) on 945s. - */ - if (pitch_val > I915_FENCE_MAX_PITCH_VAL || - size > (I830_FENCE_MAX_SIZE_VAL << 20)) + } else if (IS_GEN3(dev) || IS_GEN2(dev)) { + if (stride > 8192) return false; - } else { - uint32_t pitch_val = ffs(stride / tile_width) - 1; - if (pitch_val > I830_FENCE_MAX_PITCH_VAL || - size > (I830_FENCE_MAX_SIZE_VAL << 19)) - return false; + if (IS_GEN3(dev)) { + if (size > I830_FENCE_MAX_SIZE_VAL << 20) + return false; + } else { + if (size > I830_FENCE_MAX_SIZE_VAL << 19) + return false; + } } /* 965+ just needs multiples of tile width */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6421481d622..2b8b969d0c1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -349,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) READ_BREADCRUMB(dev_priv); } - if (gt_iir & GT_USER_INTERRUPT) { + if (gt_iir & GT_PIPE_NOTIFY) { u32 seqno = i915_get_gem_seqno(dev); dev_priv->mm.irq_gem_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); @@ -1005,7 +1005,7 @@ void i915_user_irq_get(struct drm_device *dev) spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { if (HAS_PCH_SPLIT(dev)) - ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); + ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); else i915_enable_irq(dev_priv, I915_USER_INTERRUPT); } @@ -1021,7 +1021,7 @@ void i915_user_irq_put(struct drm_device *dev) BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { if (HAS_PCH_SPLIT(dev)) - ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); + ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); else i915_disable_irq(dev_priv, I915_USER_INTERRUPT); } @@ -1305,7 +1305,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) /* enable kind of interrupts always enabled */ u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; - u32 render_mask = GT_USER_INTERRUPT; + u32 render_mask = GT_PIPE_NOTIFY; u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index 7cc8410239c..8fcc75c1aa2 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c @@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_opregion *opregion = &dev_priv->opregion; struct drm_connector *connector; + acpi_handle handle; + struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; + unsigned long long device_id; + acpi_status status; int i = 0; + handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) + return; + + if (acpi_is_video_device(acpi_dev)) + acpi_video_bus = acpi_dev; + else { + list_for_each_entry(acpi_cdev, &acpi_dev->children, node) { + if (acpi_is_video_device(acpi_cdev)) { + acpi_video_bus = acpi_cdev; + break; + } + } + } + + if (!acpi_video_bus) { + printk(KERN_WARNING "No ACPI video bus found\n"); + return; + } + + list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { + if (i >= 8) { + dev_printk (KERN_ERR, &dev->pdev->dev, + "More than 8 outputs detected\n"); + return; + } + status = + acpi_evaluate_integer(acpi_cdev->handle, "_ADR", + NULL, &device_id); + if (ACPI_SUCCESS(status)) { + if (!device_id) + goto blind_set; + opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f); + i++; + } + } + +end: + /* If fewer than 8 outputs, the list must be null terminated */ + if (i < 8) + opregion->acpi->didl[i] = 0; + return; + +blind_set: + i = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { int output_type = ACPI_OTHER_OUTPUT; if (i >= 8) { @@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev) opregion->acpi->didl[i] |= (1<<31) | output_type | i; i++; } - - /* If fewer than 8 outputs, the list must be null terminated */ - if (i < 8) - opregion->acpi->didl[i] = 0; + goto end; } int intel_opregion_init(struct drm_device *dev, int resume) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cbbf59f56df..4cbc5210fd3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -230,6 +230,16 @@ #define ASYNC_FLIP (1<<22) #define DISPLAY_PLANE_A (0<<20) #define DISPLAY_PLANE_B (1<<20) +#define GFX_OP_PIPE_CONTROL ((0x3<<29)|(0x3<<27)|(0x2<<24)|2) +#define PIPE_CONTROL_QW_WRITE (1<<14) +#define PIPE_CONTROL_DEPTH_STALL (1<<13) +#define PIPE_CONTROL_WC_FLUSH (1<<12) +#define PIPE_CONTROL_IS_FLUSH (1<<11) /* MBZ on Ironlake */ +#define PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */ +#define PIPE_CONTROL_ISP_DIS (1<<9) +#define PIPE_CONTROL_NOTIFY (1<<8) +#define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ +#define PIPE_CONTROL_STALL_EN (1<<1) /* in addr word, Ironlake+ only */ /* * Fence registers @@ -241,7 +251,7 @@ #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) #define I830_FENCE_PITCH_SHIFT 4 #define I830_FENCE_REG_VALID (1<<0) -#define I915_FENCE_MAX_PITCH_VAL 0x10 +#define I915_FENCE_MAX_PITCH_VAL 4 #define I830_FENCE_MAX_PITCH_VAL 6 #define I830_FENCE_MAX_SIZE_VAL (1<<8) @@ -2285,6 +2295,7 @@ #define DEIER 0x4400c /* GT interrupt */ +#define GT_PIPE_NOTIFY (1 << 4) #define GT_SYNC_STATUS (1 << 2) #define GT_USER_INTERRUPT (1 << 0) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e7356fb6c91..c7502b6b160 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4853,17 +4853,18 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.update_wm = g4x_update_wm; else if (IS_I965G(dev)) dev_priv->display.update_wm = i965_update_wm; - else if (IS_I9XX(dev) || IS_MOBILE(dev)) { + else if (IS_I9XX(dev)) { dev_priv->display.update_wm = i9xx_update_wm; dev_priv->display.get_fifo_size = i9xx_get_fifo_size; + } else if (IS_I85X(dev)) { + dev_priv->display.update_wm = i9xx_update_wm; + dev_priv->display.get_fifo_size = i85x_get_fifo_size; } else { - if (IS_I85X(dev)) - dev_priv->display.get_fifo_size = i85x_get_fifo_size; - else if (IS_845G(dev)) + dev_priv->display.update_wm = i830_update_wm; + if (IS_845G(dev)) dev_priv->display.get_fifo_size = i845_get_fifo_size; else dev_priv->display.get_fifo_size = i830_get_fifo_size; - dev_priv->display.update_wm = i830_update_wm; } } diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 75f3fa55663..16c42024072 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -1169,15 +1169,19 @@ static int atk_create_files(struct atk_data *data) int err; list_for_each_entry(s, &data->sensor_list, list) { + sysfs_attr_init(&s->input_attr.attr); err = device_create_file(data->hwmon_dev, &s->input_attr); if (err) return err; + sysfs_attr_init(&s->label_attr.attr); err = device_create_file(data->hwmon_dev, &s->label_attr); if (err) return err; + sysfs_attr_init(&s->limit1_attr.attr); err = device_create_file(data->hwmon_dev, &s->limit1_attr); if (err) return err; + sysfs_attr_init(&s->limit2_attr.attr); err = device_create_file(data->hwmon_dev, &s->limit2_attr); if (err) return err; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 20e48401910..58ea0ecae7c 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1650,7 +1650,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, int previous, int *dd_idx, struct stripe_head *sh) { - sector_t stripe; + sector_t stripe, stripe2; sector_t chunk_number; unsigned int chunk_offset; int pd_idx, qd_idx; @@ -1677,7 +1677,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, */ stripe = chunk_number; *dd_idx = sector_div(stripe, data_disks); - + stripe2 = stripe; /* * Select the parity disk based on the user selected algorithm. */ @@ -1689,21 +1689,21 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, case 5: switch (algorithm) { case ALGORITHM_LEFT_ASYMMETRIC: - pd_idx = data_disks - stripe % raid_disks; + pd_idx = data_disks - sector_div(stripe2, raid_disks); if (*dd_idx >= pd_idx) (*dd_idx)++; break; case ALGORITHM_RIGHT_ASYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); if (*dd_idx >= pd_idx) (*dd_idx)++; break; case ALGORITHM_LEFT_SYMMETRIC: - pd_idx = data_disks - stripe % raid_disks; + pd_idx = data_disks - sector_div(stripe2, raid_disks); *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; break; case ALGORITHM_RIGHT_SYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; break; case ALGORITHM_PARITY_0: @@ -1723,7 +1723,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, switch (algorithm) { case ALGORITHM_LEFT_ASYMMETRIC: - pd_idx = raid_disks - 1 - (stripe % raid_disks); + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1732,7 +1732,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, (*dd_idx) += 2; /* D D P Q D */ break; case ALGORITHM_RIGHT_ASYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1741,12 +1741,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, (*dd_idx) += 2; /* D D P Q D */ break; case ALGORITHM_LEFT_SYMMETRIC: - pd_idx = raid_disks - 1 - (stripe % raid_disks); + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = (pd_idx + 1) % raid_disks; *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; break; case ALGORITHM_RIGHT_SYMMETRIC: - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); qd_idx = (pd_idx + 1) % raid_disks; *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks; break; @@ -1765,7 +1765,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, /* Exactly the same as RIGHT_ASYMMETRIC, but or * of blocks for computing Q is different. */ - pd_idx = stripe % raid_disks; + pd_idx = sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1780,7 +1780,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, * D D D P Q rather than * Q D D D P */ - pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks); + stripe2 += 1; + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = pd_idx + 1; if (pd_idx == raid_disks-1) { (*dd_idx)++; /* Q D D D P */ @@ -1792,7 +1793,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, case ALGORITHM_ROTATING_N_CONTINUE: /* Same as left_symmetric but Q is before P */ - pd_idx = raid_disks - 1 - (stripe % raid_disks); + pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks); qd_idx = (pd_idx + raid_disks - 1) % raid_disks; *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks; ddf_layout = 1; @@ -1800,27 +1801,27 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, case ALGORITHM_LEFT_ASYMMETRIC_6: /* RAID5 left_asymmetric, with Q on last device */ - pd_idx = data_disks - stripe % (raid_disks-1); + pd_idx = data_disks - sector_div(stripe2, raid_disks-1); if (*dd_idx >= pd_idx) (*dd_idx)++; qd_idx = raid_disks - 1; break; case ALGORITHM_RIGHT_ASYMMETRIC_6: - pd_idx = stripe % (raid_disks-1); + pd_idx = sector_div(stripe2, raid_disks-1); if (*dd_idx >= pd_idx) (*dd_idx)++; qd_idx = raid_disks - 1; break; case ALGORITHM_LEFT_SYMMETRIC_6: - pd_idx = data_disks - stripe % (raid_disks-1); + pd_idx = data_disks - sector_div(stripe2, raid_disks-1); *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); qd_idx = raid_disks - 1; break; case ALGORITHM_RIGHT_SYMMETRIC_6: - pd_idx = stripe % (raid_disks-1); + pd_idx = sector_div(stripe2, raid_disks-1); *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1); qd_idx = raid_disks - 1; break; diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 09d6d4b76f3..caeb7d10ae0 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -467,7 +467,7 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, if (conn_err_detail) *conn_err_detail = mbox_sts[5]; if (tcp_source_port_num) - *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16; + *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16); if (connection_id) *connection_id = (uint16_t) mbox_sts[6] & 0x00FF; status = QLA_SUCCESS; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 6a3b5cae3a6..2f3dc4cdf79 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -301,7 +301,7 @@ static int usb_probe_interface(struct device *dev) intf->condition = USB_INTERFACE_BINDING; - /* Bound interfaces are initially active. They are + /* Probed interfaces are initially active. They are * runtime-PM-enabled only if the driver has autosuspend support. * They are sensitive to their children's power states. */ @@ -437,11 +437,11 @@ int usb_driver_claim_interface(struct usb_driver *driver, iface->condition = USB_INTERFACE_BOUND; - /* Bound interfaces are initially active. They are + /* Claimed interfaces are initially inactive (suspended). They are * runtime-PM-enabled only if the driver has autosuspend support. * They are sensitive to their children's power states. */ - pm_runtime_set_active(dev); + pm_runtime_set_suspended(dev); pm_suspend_ignore_children(dev, false); if (driver->supports_autosuspend) pm_runtime_enable(dev); @@ -1170,7 +1170,7 @@ done: static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) { int status = 0; - int i = 0; + int i = 0, n = 0; struct usb_interface *intf; if (udev->state == USB_STATE_NOTATTACHED || @@ -1179,7 +1179,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) /* Suspend all the interfaces and then udev itself */ if (udev->actconfig) { - for (; i < udev->actconfig->desc.bNumInterfaces; i++) { + n = udev->actconfig->desc.bNumInterfaces; + for (i = n - 1; i >= 0; --i) { intf = udev->actconfig->interface[i]; status = usb_suspend_interface(udev, intf, msg); if (status != 0) @@ -1192,7 +1193,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) /* If the suspend failed, resume interfaces that did get suspended */ if (status != 0) { msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); - while (--i >= 0) { + while (++i < n) { intf = udev->actconfig->interface[i]; usb_resume_interface(udev, intf, msg, 0); } @@ -1263,13 +1264,47 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) return status; } +static void choose_wakeup(struct usb_device *udev, pm_message_t msg) +{ + int w, i; + struct usb_interface *intf; + + /* Remote wakeup is needed only when we actually go to sleep. + * For things like FREEZE and QUIESCE, if the device is already + * autosuspended then its current wakeup setting is okay. + */ + if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) { + if (udev->state != USB_STATE_SUSPENDED) + udev->do_remote_wakeup = 0; + return; + } + + /* If remote wakeup is permitted, see whether any interface drivers + * actually want it. + */ + w = 0; + if (device_may_wakeup(&udev->dev) && udev->actconfig) { + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; + w |= intf->needs_remote_wakeup; + } + } + + /* If the device is autosuspended with the wrong wakeup setting, + * autoresume now so the setting can be changed. + */ + if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup) + pm_runtime_resume(&udev->dev); + udev->do_remote_wakeup = w; +} + /* The device lock is held by the PM core */ int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev = to_usb_device(dev); do_unbind_rebind(udev, DO_UNBIND); - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); + choose_wakeup(udev, msg); return usb_suspend_both(udev, msg); } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 207e7a85aeb..13ead00aecd 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd) */ ehci->periodic_size = DEFAULT_I_TDPS; INIT_LIST_HEAD(&ehci->cached_itd_list); + INIT_LIST_HEAD(&ehci->cached_sitd_list); if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) return retval; diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 19372673bf0..c7178bcde67 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -801,7 +801,7 @@ static int ehci_hub_control ( * this bit; seems too long to spin routinely... */ retval = handshake(ehci, status_reg, - PORT_RESET, 0, 750); + PORT_RESET, 0, 1000); if (retval != 0) { ehci_err (ehci, "port %d reset error %d\n", wIndex + 1, retval); diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index aeda96e0af6..1f3f01eacaf 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_qh *qh) static void ehci_mem_cleanup (struct ehci_hcd *ehci) { - free_cached_itd_list(ehci); + free_cached_lists(ehci); if (ehci->async) qh_put (ehci->async); ehci->async = NULL; diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index a67a0030dd5..40a85833503 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -629,11 +629,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } snprintf(supply, sizeof(supply), "hsusb%d", i); omap->regulator[i] = regulator_get(omap->dev, supply); - if (IS_ERR(omap->regulator[i])) + if (IS_ERR(omap->regulator[i])) { + omap->regulator[i] = NULL; dev_dbg(&pdev->dev, "failed to get ehci port%d regulator\n", i); - else + } else { regulator_enable(omap->regulator[i]); + } } ret = omap_start_ehc(omap, hcd); diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index a0aaaaff256..805ec633a65 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -510,7 +510,7 @@ static int disable_periodic (struct ehci_hcd *ehci) ehci_writel(ehci, cmd, &ehci->regs->command); /* posted write ... */ - free_cached_itd_list(ehci); + free_cached_lists(ehci); ehci->next_uframe = -1; return 0; @@ -2139,13 +2139,27 @@ sitd_complete ( (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } iso_stream_put (ehci, stream); - /* OK to recycle this SITD now that its completion callback ran. */ + done: sitd->urb = NULL; - sitd->stream = NULL; - list_move(&sitd->sitd_list, &stream->free_list); - iso_stream_put(ehci, stream); - + if (ehci->clock_frame != sitd->frame) { + /* OK to recycle this SITD now. */ + sitd->stream = NULL; + list_move(&sitd->sitd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } else { + /* HW might remember this SITD, so we can't recycle it yet. + * Move it to a safe place until a new frame starts. + */ + list_move(&sitd->sitd_list, &ehci->cached_sitd_list); + if (stream->refcount == 2) { + /* If iso_stream_put() were called here, stream + * would be freed. Instead, just prevent reuse. + */ + stream->ep->hcpriv = NULL; + stream->ep = NULL; + } + } return retval; } @@ -2211,9 +2225,10 @@ done: /*-------------------------------------------------------------------------*/ -static void free_cached_itd_list(struct ehci_hcd *ehci) +static void free_cached_lists(struct ehci_hcd *ehci) { struct ehci_itd *itd, *n; + struct ehci_sitd *sitd, *sn; list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { struct ehci_iso_stream *stream = itd->stream; @@ -2221,6 +2236,13 @@ static void free_cached_itd_list(struct ehci_hcd *ehci) list_move(&itd->itd_list, &stream->free_list); iso_stream_put(ehci, stream); } + + list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) { + struct ehci_iso_stream *stream = sitd->stream; + sitd->stream = NULL; + list_move(&sitd->sitd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } } /*-------------------------------------------------------------------------*/ @@ -2247,7 +2269,7 @@ scan_periodic (struct ehci_hcd *ehci) clock_frame = -1; } if (ehci->clock_frame != clock_frame) { - free_cached_itd_list(ehci); + free_cached_lists(ehci); ehci->clock_frame = clock_frame; } clock %= mod; @@ -2414,7 +2436,7 @@ restart: clock = now; clock_frame = clock >> 3; if (ehci->clock_frame != clock_frame) { - free_cached_itd_list(ehci); + free_cached_lists(ehci); ehci->clock_frame = clock_frame; } } else { diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index b1dce96dd62..556c0b48f3a 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -87,8 +87,9 @@ struct ehci_hcd { /* one per controller */ int next_uframe; /* scan periodic, start here */ unsigned periodic_sched; /* periodic activity count */ - /* list of itds completed while clock_frame was still active */ + /* list of itds & sitds completed while clock_frame was still active */ struct list_head cached_itd_list; + struct list_head cached_sitd_list; unsigned clock_frame; /* per root hub port */ @@ -195,7 +196,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) clear_bit (action, &ehci->actions); } -static void free_cached_itd_list(struct ehci_hcd *ehci); +static void free_cached_lists(struct ehci_hcd *ehci); /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 4aa08d36d07..d22fb4d577b 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -23,7 +23,7 @@ #error "This file is DA8xx bus glue. Define CONFIG_ARCH_DAVINCI_DA8XX." #endif -#define CFGCHIP2 DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG) +#define CFGCHIP2 DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG) static struct clk *usb11_clk; static struct clk *usb20_clk; diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index a9555cb901a..de8ef945b53 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -49,6 +49,7 @@ struct usb_sevsegdev { u16 textlength; u8 shadow_power; /* for PM */ + u8 has_interface_pm; }; /* sysfs_streq can't replace this completely @@ -68,12 +69,16 @@ static void update_display_powered(struct usb_sevsegdev *mydev) { int rc; - if (!mydev->shadow_power && mydev->powered) { + if (mydev->powered && !mydev->has_interface_pm) { rc = usb_autopm_get_interface(mydev->intf); if (rc < 0) return; + mydev->has_interface_pm = 1; } + if (mydev->shadow_power != 1) + return; + rc = usb_control_msg(mydev->udev, usb_sndctrlpipe(mydev->udev, 0), 0x12, @@ -86,8 +91,10 @@ static void update_display_powered(struct usb_sevsegdev *mydev) if (rc < 0) dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc); - if (mydev->shadow_power && !mydev->powered) + if (!mydev->powered && mydev->has_interface_pm) { usb_autopm_put_interface(mydev->intf); + mydev->has_interface_pm = 0; + } } static void update_display_mode(struct usb_sevsegdev *mydev) @@ -351,6 +358,10 @@ static int sevseg_probe(struct usb_interface *interface, mydev->intf = interface; usb_set_intfdata(interface, mydev); + /* PM */ + mydev->shadow_power = 1; /* currently active */ + mydev->has_interface_pm = 0; /* have not issued autopm_get */ + /*set defaults */ mydev->textmode = 0x02; /* ascii mode */ mydev->mode_msb = 0x06; /* 6 characters */ diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 73d5f346d3e..c97a0bb5b6d 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -97,6 +97,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, + { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index d640dc95156..a352d5f3a59 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -134,3 +134,7 @@ /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */ #define SANWA_VENDOR_ID 0x11ad #define SANWA_PRODUCT_ID 0x0001 + +/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ +#define ADLINK_VENDOR_ID 0x0b63 +#define ADLINK_ND6530_PRODUCT_ID 0x6530 diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c index 0b936206171..7e3bea23600 100644 --- a/drivers/usb/serial/qcaux.c +++ b/drivers/usb/serial/qcaux.c @@ -42,6 +42,14 @@ #define CMOTECH_PRODUCT_CDU550 0x5553 #define CMOTECH_PRODUCT_CDX650 0x6512 +/* LG devices */ +#define LG_VENDOR_ID 0x1004 +#define LG_PRODUCT_VX4400_6000 0x6000 /* VX4400/VX6000/Rumor */ + +/* Sanyo devices */ +#define SANYO_VENDOR_ID 0x0474 +#define SANYO_PRODUCT_KATANA_LX 0x0754 /* SCP-3800 (Katana LX) */ + static struct usb_device_id id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) }, @@ -51,6 +59,8 @@ static struct usb_device_id id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 9202f94505e..ef0bdb08d78 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -230,6 +230,7 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = { static const struct usb_device_id id_table[] = { { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ + { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */ { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 0afe5c71c17..880e990abb0 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -172,7 +172,7 @@ static unsigned int product_5052_count; /* the array dimension is the number of default entries plus */ /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ /* null entry */ -static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, @@ -180,6 +180,9 @@ static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, @@ -192,7 +195,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, }; -static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, @@ -200,6 +203,9 @@ static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) }, + { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, @@ -287,6 +293,8 @@ MODULE_FIRMWARE("ti_5052.fw"); MODULE_FIRMWARE("mts_cdma.fw"); MODULE_FIRMWARE("mts_gsm.fw"); MODULE_FIRMWARE("mts_edge.fw"); +MODULE_FIRMWARE("mts_mt9234mu.fw"); +MODULE_FIRMWARE("mts_mt9234zba.fw"); module_param(debug, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes"); @@ -1687,6 +1695,7 @@ static int ti_download_firmware(struct ti_device *tdev) const struct firmware *fw_p; char buf[32]; + dbg("%s\n", __func__); /* try ID specific firmware first, then try generic firmware */ sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor, dev->descriptor.idProduct); @@ -1703,7 +1712,15 @@ static int ti_download_firmware(struct ti_device *tdev) case MTS_EDGE_PRODUCT_ID: strcpy(buf, "mts_edge.fw"); break; - } + case MTS_MT9234MU_PRODUCT_ID: + strcpy(buf, "mts_mt9234mu.fw"); + break; + case MTS_MT9234ZBA_PRODUCT_ID: + strcpy(buf, "mts_mt9234zba.fw"); + break; + case MTS_MT9234ZBAOLD_PRODUCT_ID: + strcpy(buf, "mts_mt9234zba.fw"); + break; } } if (buf[0] == '\0') { if (tdev->td_is_3410) @@ -1718,7 +1735,7 @@ static int ti_download_firmware(struct ti_device *tdev) return -ENOENT; } if (fw_p->size > TI_FIRMWARE_BUF_SIZE) { - dev_err(&dev->dev, "%s - firmware too large\n", __func__); + dev_err(&dev->dev, "%s - firmware too large %d \n", __func__, fw_p->size); return -ENOENT; } @@ -1730,6 +1747,7 @@ static int ti_download_firmware(struct ti_device *tdev) status = ti_do_download(dev, pipe, buffer, fw_p->size); kfree(buffer); } else { + dbg("%s ENOMEM\n", __func__); status = -ENOMEM; } release_firmware(fw_p); diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h index f323c602585..2aac1953993 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.h +++ b/drivers/usb/serial/ti_usb_3410_5052.h @@ -45,6 +45,9 @@ #define MTS_CDMA_PRODUCT_ID 0xF110 #define MTS_GSM_PRODUCT_ID 0xF111 #define MTS_EDGE_PRODUCT_ID 0xF112 +#define MTS_MT9234MU_PRODUCT_ID 0xF114 +#define MTS_MT9234ZBA_PRODUCT_ID 0xF115 +#define MTS_MT9234ZBAOLD_PRODUCT_ID 0x0319 /* Commands */ #define TI_GET_VERSION 0x01 diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 46e79d34949..7ec24e46b34 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -438,7 +438,7 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc) old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr); keep_alives = 0; for (cnt = 0; - keep_alives <= WUIE_ELT_MAX && cnt < wusbhc->ports_max; + keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max; cnt++) { unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout); |