From 942642a412454c3365f0abc8399c8ef2944f4eac Mon Sep 17 00:00:00 2001 From: Sean Young Date: Thu, 6 Aug 2009 17:35:50 +0800 Subject: [PATCH 01/21] drm/i915: Set the multiplier for SDVO on G33 platform http://bugs.freedesktop.org/show_bug.cgi?id=21417 Signed-off-by: Sean Young Reviewed-by: Zhao Yakui Acked-by: Zhenyu Wang Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d6fce213341..f611e216b0b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2396,7 +2396,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, if (is_sdvo) { dpll |= DPLL_DVO_HIGH_SPEED; sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; - if (IS_I945G(dev) || IS_I945GM(dev)) + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; else if (IS_IGDNG(dev)) dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; From bc5e5718acd7f7d000d913e619562767863610bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Sat, 8 Aug 2009 13:01:17 +0200 Subject: [PATCH 02/21] drm/i915: Check if BIOS enabled dual-channel LVDS on 8xx, not only on 9xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 0c2e39525b3b53a97a0202c5f35058147e53977e is not sufficient to get fd.o bug #20115 fixed. In addition intel_find_best_PLL() must not only rely on BIOS settings for i9xx chips but also for i8xx, so drop the IS_I9XX() check. Signed-off-by: Bruno Prémont Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f611e216b0b..8fd90f31b60 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -666,7 +666,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, intel_clock_t clock; int err = target; - if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && (I915_READ(LVDS)) != 0) { /* * For LVDS, if the panel is on, just rely on its current From 19e1f888c681d9f71ae0a814902d334eac1911dd Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Sun, 9 Aug 2009 13:50:53 +0200 Subject: [PATCH 03/21] drm/i915: Fix typo that broke SVID1 in intel_sdvo_multifunc_encoder() Bit SDVO_OUTPUT_SVID0 was tested twice Signed-off-by: Roel Kluin Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 5371d933255..95ca0acc494 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1458,7 +1458,7 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) caps++; if (sdvo_priv->caps.output_flags & - (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0)) + (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) caps++; if (sdvo_priv->caps.output_flags & (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) From 27185ae1b795a4ba5e25b95fb5584e950545d774 Mon Sep 17 00:00:00 2001 From: Ma Ling Date: Mon, 24 Aug 2009 13:50:23 +0800 Subject: [PATCH 04/21] drm/i915: Always use SDVO_B detect bit for SDVO output detection. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the following commit is shipped, the SDVO C detection will depend on the SDVO_C/DP detion bit. commit 13520b051e8888dd3af9bda639d83e7df76613d1 Author: Kristian Høgsberg Date: Fri Mar 13 15:42:14 2009 -0400 drm/i915: Read the right SDVO register when detecting SVDO/HDMI. According to the spec we should continue to detect the SDVO_B/C based on the SDVO_B detection bit. The new detection bit on G4X platform is for the HDMI_C detection rather than SDVO_C detection. https://bugs.freedesktop.org/show_bug.cgi?id=20639 Signed-off-by: Ma Ling Acked-by: Zhao Yakui Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_display.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8fd90f31b60..4fad113a1b2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3218,30 +3218,30 @@ static void intel_setup_outputs(struct drm_device *dev) intel_dp_init(dev, PCH_DP_D); } else if (IS_I9XX(dev)) { - int found; - u32 reg; + bool found = false; if (I915_READ(SDVOB) & SDVO_DETECTED) { found = intel_sdvo_init(dev, SDVOB); if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) intel_hdmi_init(dev, SDVOB); + if (!found && SUPPORTS_INTEGRATED_DP(dev)) intel_dp_init(dev, DP_B); } /* Before G4X SDVOC doesn't have its own detect register */ - if (IS_G4X(dev)) - reg = SDVOC; - else - reg = SDVOB; - if (I915_READ(reg) & SDVO_DETECTED) { + if (I915_READ(SDVOB) & SDVO_DETECTED) found = intel_sdvo_init(dev, SDVOC); - if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) + + if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { + + if (SUPPORTS_INTEGRATED_HDMI(dev)) intel_hdmi_init(dev, SDVOC); - if (!found && SUPPORTS_INTEGRATED_DP(dev)) + if (SUPPORTS_INTEGRATED_DP(dev)) intel_dp_init(dev, DP_C); } + if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) intel_dp_init(dev, DP_D); } else From f8aed700c6ec46ddade6570004ce25332283b306 Mon Sep 17 00:00:00 2001 From: Ma Ling Date: Mon, 24 Aug 2009 13:50:24 +0800 Subject: [PATCH 05/21] drm/i915: Set crtc/clone mask in different output devices Based on Bspec each encoder has different sharing pipe property, i.e. Integrated or SDVO TV both will occupy one pipe exclusively, and sdvo-non-tv and crt are allowed to share one. The patch moves sharing judgment into differnet output functions, and sets the right clone bit. This fixes both HDMI outputs choosing the same pipe. https://bugs.freedesktop.org/show_bug.cgi?id=22247 Signed-off-by: Ma Ling Reviewed-by : Jesse Barnes Signed-off-by: Zhao Yakui Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/intel_crt.c | 4 +++ drivers/gpu/drm/i915/intel_display.c | 49 +++------------------------- drivers/gpu/drm/i915/intel_dp.c | 12 +++++++ drivers/gpu/drm/i915/intel_drv.h | 20 ++++++++++++ drivers/gpu/drm/i915/intel_dvo.c | 6 ++++ drivers/gpu/drm/i915/intel_hdmi.c | 18 ++++++---- drivers/gpu/drm/i915/intel_lvds.c | 2 ++ drivers/gpu/drm/i915/intel_sdvo.c | 11 +++++++ drivers/gpu/drm/i915/intel_tv.c | 2 ++ 9 files changed, 73 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 4cf8e2e88a4..d1294978a38 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -537,6 +537,10 @@ void intel_crt_init(struct drm_device *dev) } intel_output->type = INTEL_OUTPUT_ANALOG; + intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + (1 << INTEL_ANALOG_CLONE_BIT) | + (1 << INTEL_SDVO_LVDS_CLONE_BIT); + intel_output->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = 0; connector->doublescan_allowed = 0; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4fad113a1b2..3fadb535885 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3170,7 +3170,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct intel_output *intel_output = to_intel_output(connector); - if (type_mask & (1 << intel_output->type)) + if (type_mask & intel_output->clone_mask) index_mask |= (1 << entry); entry++; } @@ -3253,51 +3253,10 @@ static void intel_setup_outputs(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct intel_output *intel_output = to_intel_output(connector); struct drm_encoder *encoder = &intel_output->enc; - int crtc_mask = 0, clone_mask = 0; - /* valid crtcs */ - switch(intel_output->type) { - case INTEL_OUTPUT_HDMI: - crtc_mask = ((1 << 0)| - (1 << 1)); - clone_mask = ((1 << INTEL_OUTPUT_HDMI)); - break; - case INTEL_OUTPUT_DVO: - case INTEL_OUTPUT_SDVO: - crtc_mask = ((1 << 0)| - (1 << 1)); - clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | - (1 << INTEL_OUTPUT_DVO) | - (1 << INTEL_OUTPUT_SDVO)); - break; - case INTEL_OUTPUT_ANALOG: - crtc_mask = ((1 << 0)| - (1 << 1)); - clone_mask = ((1 << INTEL_OUTPUT_ANALOG) | - (1 << INTEL_OUTPUT_DVO) | - (1 << INTEL_OUTPUT_SDVO)); - break; - case INTEL_OUTPUT_LVDS: - crtc_mask = (1 << 1); - clone_mask = (1 << INTEL_OUTPUT_LVDS); - break; - case INTEL_OUTPUT_TVOUT: - crtc_mask = ((1 << 0) | - (1 << 1)); - clone_mask = (1 << INTEL_OUTPUT_TVOUT); - break; - case INTEL_OUTPUT_DISPLAYPORT: - crtc_mask = ((1 << 0) | - (1 << 1)); - clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); - break; - case INTEL_OUTPUT_EDP: - crtc_mask = (1 << 1); - clone_mask = (1 << INTEL_OUTPUT_EDP); - break; - } - encoder->possible_crtcs = crtc_mask; - encoder->possible_clones = intel_connector_clones(dev, clone_mask); + encoder->possible_crtcs = intel_output->crtc_mask; + encoder->possible_clones = intel_connector_clones(dev, + intel_output->clone_mask); } } diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6ff15ac548..f2afc4af4bc 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1254,6 +1254,18 @@ intel_dp_init(struct drm_device *dev, int output_reg) else intel_output->type = INTEL_OUTPUT_DISPLAYPORT; + if (output_reg == DP_B) + intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); + else if (output_reg == DP_C) + intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); + else if (output_reg == DP_D) + intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); + + if (IS_eDP(intel_output)) { + intel_output->crtc_mask = (1 << 1); + intel_output->clone_mask = (1 << INTEL_OUTPUT_EDP); + } else + intel_output->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = true; connector->doublescan_allowed = 0; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d6f92ea1b55..25aa6facc12 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -57,6 +57,24 @@ #define INTEL_OUTPUT_DISPLAYPORT 7 #define INTEL_OUTPUT_EDP 8 +/* Intel Pipe Clone Bit */ +#define INTEL_HDMIB_CLONE_BIT 1 +#define INTEL_HDMIC_CLONE_BIT 2 +#define INTEL_HDMID_CLONE_BIT 3 +#define INTEL_HDMIE_CLONE_BIT 4 +#define INTEL_HDMIF_CLONE_BIT 5 +#define INTEL_SDVO_NON_TV_CLONE_BIT 6 +#define INTEL_SDVO_TV_CLONE_BIT 7 +#define INTEL_SDVO_LVDS_CLONE_BIT 8 +#define INTEL_ANALOG_CLONE_BIT 9 +#define INTEL_TV_CLONE_BIT 10 +#define INTEL_DP_B_CLONE_BIT 11 +#define INTEL_DP_C_CLONE_BIT 12 +#define INTEL_DP_D_CLONE_BIT 13 +#define INTEL_LVDS_CLONE_BIT 14 +#define INTEL_DVO_TMDS_CLONE_BIT 15 +#define INTEL_DVO_LVDS_CLONE_BIT 16 + #define INTEL_DVO_CHIP_NONE 0 #define INTEL_DVO_CHIP_LVDS 1 #define INTEL_DVO_CHIP_TMDS 2 @@ -86,6 +104,8 @@ struct intel_output { bool needs_tv_clock; void *dev_priv; void (*hot_plug)(struct intel_output *); + int crtc_mask; + int clone_mask; }; struct intel_crtc { diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 13bff20930e..a4d2606de77 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev) continue; intel_output->type = INTEL_OUTPUT_DVO; + intel_output->crtc_mask = (1 << 0) | (1 << 1); switch (dvo->type) { case INTEL_DVO_CHIP_TMDS: + intel_output->clone_mask = + (1 << INTEL_DVO_TMDS_CLONE_BIT) | + (1 << INTEL_ANALOG_CLONE_BIT); drm_connector_init(dev, connector, &intel_dvo_connector_funcs, DRM_MODE_CONNECTOR_DVII); encoder_type = DRM_MODE_ENCODER_TMDS; break; case INTEL_DVO_CHIP_LVDS: + intel_output->clone_mask = + (1 << INTEL_DVO_LVDS_CLONE_BIT); drm_connector_init(dev, connector, &intel_dvo_connector_funcs, DRM_MODE_CONNECTOR_LVDS); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1842290cded..fa304e13601 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -230,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) connector->interlace_allowed = 0; connector->doublescan_allowed = 0; + intel_output->crtc_mask = (1 << 0) | (1 << 1); /* Set up the DDC bus. */ - if (sdvox_reg == SDVOB) + if (sdvox_reg == SDVOB) { + intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); - else if (sdvox_reg == SDVOC) + } else if (sdvox_reg == SDVOC) { + intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); - else if (sdvox_reg == HDMIB) + } else if (sdvox_reg == HDMIB) { + intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, "HDMIB"); - else if (sdvox_reg == HDMIC) + } else if (sdvox_reg == HDMIC) { + intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, "HDMIC"); - else if (sdvox_reg == HDMID) + } else if (sdvox_reg == HDMID) { + intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, "HDMID"); - + } if (!intel_output->ddc_bus) goto err_connector; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 3f445a80c55..8df02ef8926 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -916,6 +916,8 @@ void intel_lvds_init(struct drm_device *dev) drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); intel_output->type = INTEL_OUTPUT_LVDS; + intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); + intel_output->crtc_mask = (1 << 1); drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 95ca0acc494..d3b74ba62b4 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1967,6 +1967,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) intel_sdvo_set_colorimetry(intel_output, SDVO_COLORIMETRY_RGB256); connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; + intel_output->clone_mask = + (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + (1 << INTEL_ANALOG_CLONE_BIT); } } else if (flags & SDVO_OUTPUT_SVID0) { @@ -1975,11 +1978,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; sdvo_priv->is_tv = true; intel_output->needs_tv_clock = true; + intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; } else if (flags & SDVO_OUTPUT_RGB0) { sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; + intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + (1 << INTEL_ANALOG_CLONE_BIT); } else if (flags & SDVO_OUTPUT_RGB1) { sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; @@ -1991,12 +1997,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; sdvo_priv->is_lvds = true; + intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | + (1 << INTEL_SDVO_LVDS_CLONE_BIT); } else if (flags & SDVO_OUTPUT_LVDS1) { sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; sdvo_priv->is_lvds = true; + intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | + (1 << INTEL_SDVO_LVDS_CLONE_BIT); } else { unsigned char bytes[2]; @@ -2009,6 +2019,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) bytes[0], bytes[1]); ret = false; } + intel_output->crtc_mask = (1 << 0) | (1 << 1); if (ret && registered) ret = drm_sysfs_connector_add(connector) == 0 ? true : false; diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index da4ab4dc163..2fbe13a0de8 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1718,6 +1718,7 @@ intel_tv_init(struct drm_device *dev) if (!intel_output) { return; } + connector = &intel_output->base; drm_connector_init(dev, connector, &intel_tv_connector_funcs, @@ -1729,6 +1730,7 @@ intel_tv_init(struct drm_device *dev) drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); tv_priv = (struct intel_tv_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_TVOUT; + intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); intel_output->dev_priv = tv_priv; From a09ba7faf75fa4b21980d81de8e5f3d5c0785ccf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 29 Aug 2009 12:49:51 -0700 Subject: [PATCH 06/21] drm/i915: Fix CPU-spinning hangs related to fence usage by using an LRU. The lack of a proper LRU was partially worked around by taking the fence from the object containing the oldest seqno. But if there are multiple objects inactive, then they don't have seqnos and the first fence reg among them would be chosen. If you were trying to copy data between two mappings, this could result in each page fault stealing the fence from the other argument, and your application hanging. https://bugs.freedesktop.org/show_bug.cgi?id=23566 https://bugs.freedesktop.org/show_bug.cgi?id=23220 https://bugs.freedesktop.org/show_bug.cgi?id=23253 https://bugs.freedesktop.org/show_bug.cgi?id=23366 Cc: Stable Team Signed-off-by: Eric Anholt Reviewed-by: Jesse Barnes Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 6 +++ drivers/gpu/drm/i915/i915_gem.c | 86 ++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7537f57d8a8..11fc4b66c88 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -384,6 +384,9 @@ typedef struct drm_i915_private { */ struct list_head inactive_list; + /** LRU list of objects with fence regs on them. */ + struct list_head fence_list; + /** * List of breadcrumbs associated with GPU requests currently * outstanding. @@ -451,6 +454,9 @@ struct drm_i915_gem_object { /** This object's place on the active/flushing/inactive lists */ struct list_head list; + /** This object's place on the fenced object LRU */ + struct list_head fence_list; + /** * This is set if the object is on the active or flushing lists * (has pending rendering), and is not set if it's on inactive (ready diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 140bee142fc..0c07a755b3a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -978,6 +978,7 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_set_domain *args = data; struct drm_gem_object *obj; uint32_t read_domains = args->read_domains; @@ -1010,8 +1011,18 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, obj, obj->size, read_domains, write_domain); #endif if (read_domains & I915_GEM_DOMAIN_GTT) { + struct drm_i915_gem_object *obj_priv = obj->driver_private; + ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); + /* Update the LRU on the fence for the CPU access that's + * about to occur. + */ + if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { + list_move_tail(&obj_priv->fence_list, + &dev_priv->mm.fence_list); + } + /* Silently promote "you're not bound, there was nothing to do" * to success, since the client was just asking us to * make sure everything was done. @@ -1155,8 +1166,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } /* Need a new fence register? */ - if (obj_priv->fence_reg == I915_FENCE_REG_NONE && - obj_priv->tiling_mode != I915_TILING_NONE) { + if (obj_priv->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj); if (ret) { mutex_unlock(&dev->struct_mutex); @@ -2208,6 +2218,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) struct drm_i915_gem_object *old_obj_priv = NULL; int i, ret, avail; + /* Just update our place in the LRU if our fence is getting used. */ + if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { + list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); + return 0; + } + switch (obj_priv->tiling_mode) { case I915_TILING_NONE: WARN(1, "allocating a fence for non-tiled object?\n"); @@ -2229,7 +2245,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) } /* First try to find a free reg */ -try_again: avail = 0; for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { reg = &dev_priv->fence_regs[i]; @@ -2243,52 +2258,41 @@ try_again: /* None available, try to steal one or wait for a user to finish */ if (i == dev_priv->num_fence_regs) { - uint32_t seqno = dev_priv->mm.next_gem_seqno; + struct drm_gem_object *old_obj = NULL; if (avail == 0) return -ENOSPC; - for (i = dev_priv->fence_reg_start; - i < dev_priv->num_fence_regs; i++) { - uint32_t this_seqno; + list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list, + fence_list) { + old_obj = old_obj_priv->obj; - reg = &dev_priv->fence_regs[i]; - old_obj_priv = reg->obj->driver_private; + reg = &dev_priv->fence_regs[old_obj_priv->fence_reg]; if (old_obj_priv->pin_count) continue; + /* Take a reference, as otherwise the wait_rendering + * below may cause the object to get freed out from + * under us. + */ + drm_gem_object_reference(old_obj); + /* i915 uses fences for GPU access to tiled buffers */ if (IS_I965G(dev) || !old_obj_priv->active) break; - /* find the seqno of the first available fence */ - this_seqno = old_obj_priv->last_rendering_seqno; - if (this_seqno != 0 && - reg->obj->write_domain == 0 && - i915_seqno_passed(seqno, this_seqno)) - seqno = this_seqno; - } - - /* - * Now things get ugly... we have to wait for one of the - * objects to finish before trying again. - */ - if (i == dev_priv->num_fence_regs) { - if (seqno == dev_priv->mm.next_gem_seqno) { - i915_gem_flush(dev, - I915_GEM_GPU_DOMAINS, - I915_GEM_GPU_DOMAINS); - seqno = i915_add_request(dev, NULL, - I915_GEM_GPU_DOMAINS); - if (seqno == 0) - return -ENOMEM; - } - - ret = i915_wait_request(dev, seqno); - if (ret) + /* This brings the object to the head of the LRU if it + * had been written to. The only way this should + * result in us waiting longer than the expected + * optimal amount of time is if there was a + * fence-using buffer later that was read-only. + */ + i915_gem_object_flush_gpu_write_domain(old_obj); + ret = i915_gem_object_wait_rendering(old_obj); + if (ret != 0) return ret; - goto try_again; + break; } /* @@ -2296,10 +2300,15 @@ try_again: * for this object next time we need it. */ i915_gem_release_mmap(reg->obj); + i = old_obj_priv->fence_reg; old_obj_priv->fence_reg = I915_FENCE_REG_NONE; + list_del_init(&old_obj_priv->fence_list); + drm_gem_object_unreference(old_obj); } obj_priv->fence_reg = i; + list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list); + reg->obj = obj; if (IS_I965G(dev)) @@ -2342,6 +2351,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; obj_priv->fence_reg = I915_FENCE_REG_NONE; + list_del_init(&obj_priv->fence_list); } /** @@ -3595,9 +3605,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) * Pre-965 chips need a fence register set up in order to * properly handle tiled surfaces. */ - if (!IS_I965G(dev) && - obj_priv->fence_reg == I915_FENCE_REG_NONE && - obj_priv->tiling_mode != I915_TILING_NONE) { + if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj); if (ret != 0) { if (ret != -EBUSY && ret != -ERESTARTSYS) @@ -3806,6 +3814,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) obj_priv->obj = obj; obj_priv->fence_reg = I915_FENCE_REG_NONE; INIT_LIST_HEAD(&obj_priv->list); + INIT_LIST_HEAD(&obj_priv->fence_list); return 0; } @@ -4253,6 +4262,7 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.flushing_list); INIT_LIST_HEAD(&dev_priv->mm.inactive_list); INIT_LIST_HEAD(&dev_priv->mm.request_list); + INIT_LIST_HEAD(&dev_priv->mm.fence_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, i915_gem_retire_work_handler); dev_priv->mm.next_gem_seqno = 1; From db54501900ad3665dd669f5708ecd04fc5aed495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller=20=28ELSOFT=20AG=29?= Date: Sat, 29 Aug 2009 08:54:45 +0200 Subject: [PATCH 07/21] drm/i915: Improve CRTDDC mapping by using VBT info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use VBT information to determine which DDC bus to use for CRTDCC. Fall back to GPIOA if VBT info is not available. Signed-off-by: David Müller Reviewed-by: Jesse Barnes Signed-off-by: Eric Anholt Tested on: 855 (David), and 945GM, 965GM, GM45, and G45 (anholt) --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_bios.c | 51 +++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_crt.c | 7 ++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 11fc4b66c88..5b4f87e5562 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -222,6 +222,7 @@ typedef struct drm_i915_private { unsigned int edp_support:1; int lvds_ssc_freq; + int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */ diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 300aee3296c..f806fcc54e0 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id) return NULL; } +static u16 +get_blocksize(void *p) +{ + u16 *block_ptr, block_size; + + block_ptr = (u16 *)((char *)p - 2); + block_size = *block_ptr; + return block_size; +} + static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, struct lvds_dvo_timing *dvo_timing) @@ -214,6 +224,41 @@ parse_general_features(struct drm_i915_private *dev_priv, } } +static void +parse_general_definitions(struct drm_i915_private *dev_priv, + struct bdb_header *bdb) +{ + struct bdb_general_definitions *general; + const int crt_bus_map_table[] = { + GPIOB, + GPIOA, + GPIOC, + GPIOD, + GPIOE, + GPIOF, + }; + + /* Set sensible defaults in case we can't find the general block + or it is the wrong chipset */ + dev_priv->crt_ddc_bus = -1; + + general = find_section(bdb, BDB_GENERAL_DEFINITIONS); + if (general) { + u16 block_size = get_blocksize(general); + if (block_size >= sizeof(*general)) { + int bus_pin = general->crt_ddc_gmbus_pin; + DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin); + if ((bus_pin >= 1) && (bus_pin <= 6)) { + dev_priv->crt_ddc_bus = + crt_bus_map_table[bus_pin-1]; + } + } else { + DRM_DEBUG("BDB_GD too small (%d). Invalid.\n", + block_size); + } + } +} + static void parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, struct bdb_header *bdb) @@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, struct bdb_general_definitions *p_defs; struct child_device_config *p_child; int i, child_device_num, count; - u16 block_size, *block_ptr; + u16 block_size; p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); if (!p_defs) { @@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, return; } /* get the block size of general definitions */ - block_ptr = (u16 *)((char *)p_defs - 2); - block_size = *block_ptr; + block_size = get_blocksize(p_defs); /* get the number of child device */ child_device_num = (block_size - sizeof(*p_defs)) / sizeof(*p_child); @@ -362,6 +406,7 @@ intel_init_bios(struct drm_device *dev) /* Grab useful general definitions */ parse_general_features(dev_priv, bdb); + parse_general_definitions(dev_priv, bdb); parse_lfp_panel_data(dev_priv, bdb); parse_sdvo_panel_data(dev_priv, bdb); parse_sdvo_device_mapping(dev_priv, bdb); diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index d1294978a38..590f81c8f59 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -508,6 +508,7 @@ void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; struct intel_output *intel_output; + struct drm_i915_private *dev_priv = dev->dev_private; u32 i2c_reg; intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); @@ -527,8 +528,12 @@ void intel_crt_init(struct drm_device *dev) /* Set up the DDC bus. */ if (IS_IGDNG(dev)) i2c_reg = PCH_GPIOA; - else + else { i2c_reg = GPIOA; + /* Use VBT information for CRT DDC if available */ + if (dev_priv->crt_ddc_bus != -1) + i2c_reg = dev_priv->crt_ddc_bus; + } intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); if (!intel_output->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " From 3746b6178070958279010d112703bca9cdc15e0a Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 12 Jul 2009 23:30:14 -0300 Subject: [PATCH 08/21] V4L/DVB (12446): sms1xxx: restore GPIO functionality for all Hauppauge devices Previous changesets broke Hauppauge devices and their GPIO configurations. This changeset restores the LED & LNA functionality. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 3ee1c3902c5..266033ae278 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -325,6 +325,16 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, 0 : -ETIME; } +static inline int led_feedback(struct smsdvb_client_t *client) +{ + if (client->fe_status & FE_HAS_LOCK) + return sms_board_led_feedback(client->coredev, + (client->sms_stat_dvb.ReceptionData.BER + == 0) ? SMS_LED_HI : SMS_LED_LO); + else + return sms_board_led_feedback(client->coredev, SMS_LED_OFF); +} + static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) { struct smsdvb_client_t *client; @@ -332,6 +342,8 @@ static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) *stat = client->fe_status; + led_feedback(client); + return 0; } @@ -342,6 +354,8 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) *ber = client->sms_stat_dvb.ReceptionData.BER; + led_feedback(client); + return 0; } @@ -359,6 +373,8 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) (client->sms_stat_dvb.ReceptionData.InBandPwr + 95) * 3 / 2; + led_feedback(client); + return 0; } @@ -369,6 +385,8 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) *snr = client->sms_stat_dvb.ReceptionData.SNR; + led_feedback(client); + return 0; } @@ -379,6 +397,8 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; + led_feedback(client); + return 0; } @@ -404,6 +424,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, u32 Data[3]; } Msg; + int ret; + client->fe_status = FE_HAS_SIGNAL; client->event_fe_state = -1; client->event_unc_state = -1; @@ -426,6 +448,23 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, case BANDWIDTH_AUTO: return -EOPNOTSUPP; default: return -EINVAL; } + /* Disable LNA, if any. An error is returned if no LNA is present */ + ret = sms_board_lna_control(client->coredev, 0); + if (ret == 0) { + fe_status_t status; + + /* tune with LNA off at first */ + ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); + + smsdvb_read_status(fe, &status); + + if (status & FE_HAS_LOCK) + return ret; + + /* previous tune didnt lock - enable LNA and tune again */ + sms_board_lna_control(client->coredev, 1); + } return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); @@ -451,6 +490,8 @@ static int smsdvb_init(struct dvb_frontend *fe) struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); + sms_board_power(client->coredev, 1); + sms_board_dvb3_event(client, DVB3_EVENT_INIT); return 0; } @@ -460,6 +501,9 @@ static int smsdvb_sleep(struct dvb_frontend *fe) struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); + sms_board_led_feedback(client->coredev, SMS_LED_OFF); + sms_board_power(client->coredev, 0); + sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); return 0; From f2e26ae7c8c077d001c77b330130f98e42ccad70 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 12 Aug 2009 20:21:44 -0300 Subject: [PATCH 09/21] V4L/DVB (12449): adds webcam for Micron device MT9M111 0x143A to em28xx [mchehab@redhat.com: fix merge conflict and a few CodingStyle issues] Signed-off-by: Steve Gotthardt Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 40 +++++++++++++++++++++-- drivers/media/video/em28xx/em28xx.h | 1 + 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ed281f56594..494560e8231 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1730,6 +1730,25 @@ static inline void em28xx_set_model(struct em28xx *dev) EM28XX_I2C_FREQ_100_KHZ; } + +/* FIXME: Should be replaced by a proper mt9m111 driver */ +static int em28xx_initialize_mt9m111(struct em28xx *dev) +{ + int i; + unsigned char regs[][3] = { + { 0x0d, 0x00, 0x01, }, /* reset and use defaults */ + { 0x0d, 0x00, 0x00, }, + { 0x0a, 0x00, 0x21, }, + { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */ + }; + + for (i = 0; i < ARRAY_SIZE(regs); i++) + i2c_master_send(&dev->i2c_client, ®s[i][0], 3); + + return 0; +} + + /* FIXME: Should be replaced by a proper mt9m001 driver */ static int em28xx_initialize_mt9m001(struct em28xx *dev) { @@ -1758,7 +1777,7 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev) /* HINT method: webcam I2C chips * - * This method work for webcams with Micron sensors + * This method works for webcams with Micron sensors */ static int em28xx_hint_sensor(struct em28xx *dev) { @@ -1804,6 +1823,23 @@ static int em28xx_hint_sensor(struct em28xx *dev) dev->vinctl = 0x00; break; + + case 0x143a: /* MT9M111 as found in the ECS G200 */ + dev->model = EM2750_BOARD_UNKNOWN; + em28xx_set_model(dev); + + sensor_name = "mt9m111"; + dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; + dev->em28xx_sensor = EM28XX_MT9M111; + em28xx_initialize_mt9m111(dev); + dev->sensor_xres = 640; + dev->sensor_yres = 512; + + dev->vinmode = 0x0a; + dev->vinctl = 0x00; + + break; + case 0x8431: dev->model = EM2750_BOARD_UNKNOWN; em28xx_set_model(dev); @@ -1820,7 +1856,7 @@ static int em28xx_hint_sensor(struct em28xx *dev) break; default: - printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); + printk("Unknown Micron Sensor 0x%04x\n", version); return -EINVAL; } diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 8c2dc38bca9..a2add61f7d5 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -367,6 +367,7 @@ enum em28xx_sensor { EM28XX_NOSENSOR = 0, EM28XX_MT9V011, EM28XX_MT9M001, + EM28XX_MT9M111, }; enum em28xx_adecoder { From ef2d12ce12117bb97fa35bbcf677c28e14667efa Mon Sep 17 00:00:00 2001 From: Udi Atar Date: Sun, 28 Jun 2009 04:22:55 -0300 Subject: [PATCH 10/21] V4L/DVB (12450): Siano: Fixed SDIO compilation bugs Fixed SDIO compilation bugs Also fixed a memory overrun issue in buffer management. Signed-off-by: Udi Atar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smssdio.c | 54 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c index dfaa49a53f3..d1d652e7f89 100644 --- a/drivers/media/dvb/siano/smssdio.c +++ b/drivers/media/dvb/siano/smssdio.c @@ -46,6 +46,7 @@ #define SMSSDIO_DATA 0x00 #define SMSSDIO_INT 0x04 +#define SMSSDIO_BLOCK_SIZE 128 static const struct sdio_device_id smssdio_ids[] = { {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR), @@ -85,7 +86,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size) sdio_claim_host(smsdev->func); while (size >= smsdev->func->cur_blksize) { - ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1); + ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA, + buffer, smsdev->func->cur_blksize); if (ret) goto out; @@ -94,8 +96,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size) } if (size) { - ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA, - buffer, size); + ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA, + buffer, size); } out: @@ -125,23 +127,23 @@ static void smssdio_interrupt(struct sdio_func *func) */ isr = sdio_readb(func, SMSSDIO_INT, &ret); if (ret) { - dev_err(&smsdev->func->dev, - "Unable to read interrupt register!\n"); + sms_err("Unable to read interrupt register!\n"); return; } if (smsdev->split_cb == NULL) { cb = smscore_getbuffer(smsdev->coredev); if (!cb) { - dev_err(&smsdev->func->dev, - "Unable to allocate data buffer!\n"); + sms_err("Unable to allocate data buffer!\n"); return; } - ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1); + ret = sdio_memcpy_fromio(smsdev->func, + cb->p, + SMSSDIO_DATA, + SMSSDIO_BLOCK_SIZE); if (ret) { - dev_err(&smsdev->func->dev, - "Error %d reading initial block!\n", ret); + sms_err("Error %d reading initial block!\n", ret); return; } @@ -152,7 +154,10 @@ static void smssdio_interrupt(struct sdio_func *func) return; } - size = hdr->msgLength - smsdev->func->cur_blksize; + if (hdr->msgLength > smsdev->func->cur_blksize) + size = hdr->msgLength - smsdev->func->cur_blksize; + else + size = 0; } else { cb = smsdev->split_cb; hdr = cb->p; @@ -162,23 +167,24 @@ static void smssdio_interrupt(struct sdio_func *func) smsdev->split_cb = NULL; } - if (hdr->msgLength > smsdev->func->cur_blksize) { + if (size) { void *buffer; - size = ALIGN(size, 128); - buffer = cb->p + hdr->msgLength; + buffer = cb->p + (hdr->msgLength - size); + size = ALIGN(size, SMSSDIO_BLOCK_SIZE); - BUG_ON(smsdev->func->cur_blksize != 128); + BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE); /* * First attempt to transfer all of it in one go... */ - ret = sdio_read_blocks(smsdev->func, buffer, - SMSSDIO_DATA, size / 128); + ret = sdio_memcpy_fromio(smsdev->func, + buffer, + SMSSDIO_DATA, + size); if (ret && ret != -EINVAL) { smscore_putbuffer(smsdev->coredev, cb); - dev_err(&smsdev->func->dev, - "Error %d reading data from card!\n", ret); + sms_err("Error %d reading data from card!\n", ret); return; } @@ -191,12 +197,12 @@ static void smssdio_interrupt(struct sdio_func *func) */ if (ret == -EINVAL) { while (size) { - ret = sdio_read_blocks(smsdev->func, - buffer, SMSSDIO_DATA, 1); + ret = sdio_memcpy_fromio(smsdev->func, + buffer, SMSSDIO_DATA, + smsdev->func->cur_blksize); if (ret) { smscore_putbuffer(smsdev->coredev, cb); - dev_err(&smsdev->func->dev, - "Error %d reading " + sms_err("Error %d reading " "data from card!\n", ret); return; } @@ -269,7 +275,7 @@ static int smssdio_probe(struct sdio_func *func, if (ret) goto release; - ret = sdio_set_block_size(func, 128); + ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE); if (ret) goto disable; From 31e0ad693fb4e1d1be19dbe1c4f5a1ab9978e810 Mon Sep 17 00:00:00 2001 From: Udi Atar Date: Thu, 13 Aug 2009 16:30:25 -0300 Subject: [PATCH 11/21] V4L/DVB (12451): Update KConfig File to enable SDIO and USB interfaces Update KConfig file to enbale selection of SDIO and USB interfaces, and add dependancy on relevant modules. [mchehab@redhat.com: fix merge conflicts, remove default: m, add missing endmenu] Signed-off-by: Udi Atar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/Kconfig | 42 +++++++++++++++++++------------- drivers/media/dvb/siano/Makefile | 9 ++++--- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig index 88847d1dcbb..8c1aed77ea3 100644 --- a/drivers/media/dvb/siano/Kconfig +++ b/drivers/media/dvb/siano/Kconfig @@ -2,25 +2,33 @@ # Siano Mobile Silicon Digital TV device configuration # -config DVB_SIANO_SMS1XXX - tristate "Siano SMS1XXX USB dongle support" - depends on DVB_CORE && USB && INPUT +config SMS_SIANO_MDTV + tristate "Siano SMS1xxx based MDTV receiver" + depends on DVB_CORE && INPUT ---help--- - Choose Y here if you have a USB dongle with a SMS1XXX chipset. + Choose Y or M here if you have MDTV receiver with a Siano chipset. - To compile this driver as a module, choose M here: the - module will be called sms1xxx. + To compile this driver as a module, choose M here + (The module will be called smsmdtv). -config DVB_SIANO_SMS1XXX_SMS_IDS - bool "Enable support for Siano Mobile Silicon default USB IDs" - depends on DVB_SIANO_SMS1XXX - default y + Further documentation on this driver can be found on the WWW + at http://www.siano-ms.com/ + +if SMS_SIANO_MDTV +menu "Siano module components" + +# Hardware interfaces support + +config SMS_USB_DRV + tristate "USB interface support" + depends on DVB_CORE && USB ---help--- - Choose Y here if you have a USB dongle with a SMS1XXX chipset - that uses Siano Mobile Silicon's default usb vid:pid. - - Choose N here if you would prefer to use Siano's external driver. - - Further documentation on this driver can be found on the WWW at - . + Choose if you would like to have Siano's support for USB interface +config SMS_SDIO_DRV + tristate "SDIO interface support" + depends on DVB_CORE && MMC + ---help--- + Choose if you would like to have Siano's support for SDIO interface +endmenu +endif # SMS_SIANO_MDTV diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile index c6644d90943..c54140b5ab5 100644 --- a/drivers/media/dvb/siano/Makefile +++ b/drivers/media/dvb/siano/Makefile @@ -1,8 +1,9 @@ -sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o -obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o -obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o -obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o +smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o + +obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o +obj-$(CONFIG_SMS_USB_DRV) += smsusb.o +obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core From 7b808924d65a4d1a0332d0043e02e9eb5dafe32b Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 11 Aug 2009 08:10:25 -0300 Subject: [PATCH 12/21] V4L/DVB (12457): zr364: wrong indexes The order of indexes is reversed Signed-off-by: Roel Kluin Signed-off-by: Antoine Jacquet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zr364xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index fc976f42f43..2622a6e63da 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -695,7 +695,7 @@ static int zr364xx_release(struct file *file) for (i = 0; i < 2; i++) { err = send_control_msg(udev, 1, init[cam->method][i].value, - 0, init[i][cam->method].bytes, + 0, init[cam->method][i].bytes, init[cam->method][i].size); if (err < 0) { dev_err(&udev->dev, "error during release sequence\n"); From f4c5e80faba8ae420d7dc5d9237cc1e0262d7386 Mon Sep 17 00:00:00 2001 From: Shine Liu Date: Thu, 20 Aug 2009 23:49:26 -0300 Subject: [PATCH 13/21] V4L/DVB (12495): em28xx: Don't call em28xx_ir_init when disable_ir is true We should call em28xx_ir_init(dev) only when disable_ir is true. Signed-off-by: Shine Liu Reviewed-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 494560e8231..1c2e544eda7 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2382,7 +2382,9 @@ void em28xx_card_setup(struct em28xx *dev) } em28xx_tuner_setup(dev); - em28xx_ir_init(dev); + + if(!disable_ir) + em28xx_ir_init(dev); } From b6b85048c059e3f085095e48e12ed3f7a92c88d4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 26 Aug 2009 03:34:16 -0300 Subject: [PATCH 14/21] V4L/DVB (12502): gspca - sn9c20x: Fix gscpa sn9c20x build errors. Reported-by: Toralf Forster Signed-off-by: Randy Dunlap Signed-off-by: Jean-Francois Moine Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 34f46f2bc04..e994dcac43f 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig @@ -114,7 +114,7 @@ config USB_GSPCA_SN9C20X config USB_GSPCA_SN9C20X_EVDEV bool "Enable evdev support" - depends on USB_GSPCA_SN9C20X + depends on USB_GSPCA_SN9C20X && INPUT ---help--- Say Y here in order to enable evdev support for sn9c20x webcam button. From d95c5b0b905aa9b70521eeb83ad4aea85f5e5fd0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 16 Aug 2009 20:03:51 -0300 Subject: [PATCH 15/21] V4L/DVB (12564a): MAINTAINERS: Update gspca sn9c20x name style To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Signed-off-by: Joe Perches Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 60299a9a7ad..8dca9d89c6c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2239,8 +2239,7 @@ S: Maintained F: drivers/media/video/gspca/pac207.c GSPCA SN9C20X SUBDRIVER -P: Brian Johnson -M: brijohn@gmail.com +M: Brian Johnson L: linux-media@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git S: Maintained From 0f67a611629f84dd0afacd23d422b4b9c2558285 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 31 Aug 2009 08:12:29 +0200 Subject: [PATCH 16/21] ALSA: hda - Add missing mux check for VT1708 In patch_vt1708(), the check of MUX nids is missing and this results in the -EINVAL error in accessing Input Source mixer element. Simpliy adding the call of get_mux_nids() fixes the problem. Reference: Novell bnc#534904 https://bugzilla.novell.com/show_bug.cgi?id=534904 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_via.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 9008b4b013a..e8f10b10cce 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1395,6 +1395,7 @@ static int patch_vt1708(struct hda_codec *codec) if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = vt1708_adc_nids; spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); + get_mux_nids(codec); spec->mixers[spec->num_mixers] = vt1708_capture_mixer; spec->num_mixers++; } From a3f730af7e33cea10ea66f05b2565fde1f9512df Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 31 Aug 2009 08:15:26 +0200 Subject: [PATCH 17/21] ALSA: hda - Fix MacBookPro 3,1/4,1 quirk with ALC889A This patch fixes the wrong headphone output routing for MacBookPro 3,1/4,1 quirk with ALC889A codec, which caused the silent headphone output. Also, this gives the individual Headphone and Speaker volume controls. Reference: kernel bug#14078 http://bugzilla.kernel.org/show_bug.cgi?id=14078 Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_realtek.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6f683e451f2..30eeb304351 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6423,9 +6423,9 @@ static struct hda_verb alc885_mbp_ch2_init[] = { }; /* - * 6ch mode + * 4ch mode */ -static struct hda_verb alc885_mbp_ch6_init[] = { +static struct hda_verb alc885_mbp_ch4_init[] = { { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, @@ -6434,9 +6434,9 @@ static struct hda_verb alc885_mbp_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { +static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { { 2, alc885_mbp_ch2_init }, - { 6, alc885_mbp_ch6_init }, + { 4, alc885_mbp_ch4_init }, }; /* @@ -6497,10 +6497,11 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { }; static struct snd_kcontrol_new alc885_mbp3_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), - HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), - HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT), + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), + HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), + HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), @@ -6814,14 +6815,18 @@ static struct hda_verb alc885_mbp3_init_verbs[] = { {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + /* HP mixer */ + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Front Pin: output 0 (0x0c) */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* HP Pin: output 0 (0x0d) */ + /* HP Pin: output 0 (0x0e) */ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, /* Mic (rear) pin: input vref at 80% */ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, @@ -7195,10 +7200,11 @@ static struct alc_config_preset alc882_presets[] = { .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, .init_verbs = { alc885_mbp3_init_verbs, alc880_gpio1_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .num_dacs = 2, .dac_nids = alc882_dac_nids, - .channel_mode = alc885_mbp_6ch_modes, - .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes), + .hp_nid = 0x04, + .channel_mode = alc885_mbp_4ch_modes, + .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), .input_mux = &alc882_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, From 60c3be387bb6cd39707d3ec0ebc324a0c96181f8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Sun, 30 Aug 2009 14:56:30 +0200 Subject: [PATCH 18/21] ata_piix: parallel scanning on PATA needs an extra locking Commit log for commit 517d3cc15b36392e518abab6bacbb72089658313 ("[libata] ata_piix: Enable parallel scan") says: This patch turns on parallel scanning for the ata_piix driver. This driver is used on most netbooks (no AHCI for cheap storage it seems). The scan is the dominating time factor in the kernel boot for these devices; with this flag it gets cut in half for the device I used for testing (eeepc). Alan took a look at the driver source and concluded that it ought to be safe to do for this driver. Alan has also checked with the hardware team. and it is all true but once we put all things together additional constraints for PATA controllers show up (some hardware registers have per-host not per-port atomicity) and we risk misprogramming the controller. I used the following test to check whether the issue is real: @@ -736,8 +736,20 @@ static void piix_set_piomode(struct ata_ (timings[pio][1] << 8); } pci_write_config_word(dev, master_port, master_data); - if (is_slave) + if (is_slave) { + if (ap->port_no == 0) { + u8 tmp = slave_data; + + while (slave_data == tmp) { + pci_read_config_byte(dev, slave_port, &tmp); + msleep(50); + } + + dev_printk(KERN_ERR, &dev->dev, "PATA parallel scan " + "race detected\n"); + } pci_write_config_byte(dev, slave_port, slave_data); + } /* Ensure the UDMA bit is off - it will be turned back on if UDMA is selected */ and it indeed triggered the error message. Lets fix all such races by adding an extra locking to ->set_piomode and ->set_dmamode methods for PATA controllers. [ Alan: would be better to take the host lock in libata-core for these cases so that we fix all the adapters in one swoop. "Looks fine as a temproary quickfix tho" ] Cc: Arjan van de Ven Acked-by: Alan Cox Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Linus Torvalds --- drivers/ata/ata_piix.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 56b8a3ff128..9ac4e378992 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -664,6 +664,8 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline) return ata_sff_prereset(link, deadline); } +static DEFINE_SPINLOCK(piix_lock); + /** * piix_set_piomode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring @@ -677,8 +679,9 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline) static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) { - unsigned int pio = adev->pio_mode - XFER_PIO_0; struct pci_dev *dev = to_pci_dev(ap->host->dev); + unsigned long flags; + unsigned int pio = adev->pio_mode - XFER_PIO_0; unsigned int is_slave = (adev->devno != 0); unsigned int master_port= ap->port_no ? 0x42 : 0x40; unsigned int slave_port = 0x44; @@ -708,6 +711,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) if (adev->class == ATA_DEV_ATA) control |= 4; /* PPE enable */ + spin_lock_irqsave(&piix_lock, flags); + /* PIO configuration clears DTE unconditionally. It will be * programmed in set_dmamode which is guaranteed to be called * after set_piomode if any DMA mode is available. @@ -747,6 +752,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); pci_write_config_byte(dev, 0x48, udma_enable); } + + spin_unlock_irqrestore(&piix_lock, flags); } /** @@ -764,6 +771,7 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, int isich) { struct pci_dev *dev = to_pci_dev(ap->host->dev); + unsigned long flags; u8 master_port = ap->port_no ? 0x42 : 0x40; u16 master_data; u8 speed = adev->dma_mode; @@ -777,6 +785,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in { 2, 1 }, { 2, 3 }, }; + spin_lock_irqsave(&piix_lock, flags); + pci_read_config_word(dev, master_port, &master_data); if (ap->udma_mask) pci_read_config_byte(dev, 0x48, &udma_enable); @@ -867,6 +877,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in /* Don't scribble on 0x48 if the controller does not support UDMA */ if (ap->udma_mask) pci_write_config_byte(dev, 0x48, udma_enable); + + spin_unlock_irqrestore(&piix_lock, flags); } /** From 1a37f184fa7824982a5f434c06981ec46a66cef7 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 31 Aug 2009 13:48:16 +1000 Subject: [PATCH 19/21] lmb: Also remove __init from lmb_end_of_RAM() declaration in lmb.h My previous patch (commit 4f8ee2c9cc: "lmb: Remove __init from lmb_end_of_DRAM()") removed __init in lmb.c but missed the fact that it was also marked as such in the .h Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- include/linux/lmb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/lmb.h b/include/linux/lmb.h index c46c89505da..2442e3f3d03 100644 --- a/include/linux/lmb.h +++ b/include/linux/lmb.h @@ -51,7 +51,7 @@ extern u64 __init lmb_alloc_base(u64 size, extern u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr); extern u64 __init lmb_phys_mem_size(void); -extern u64 __init lmb_end_of_DRAM(void); +extern u64 lmb_end_of_DRAM(void); extern void __init lmb_enforce_memory_limit(u64 memory_limit); extern int __init lmb_is_reserved(u64 addr); extern int lmb_find(struct lmb_property *res); From 37d0892c5a94e208cf863e3b7bac014edee4346d Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 1 Sep 2009 11:26:22 +0800 Subject: [PATCH 20/21] autofs4 - fix missed case when changing to use struct path In the recent change by Al Viro that changes verious subsystems to use "struct path" one case was missed in the autofs4 module which causes mounts to no longer expire. Signed-off-by: Ian Kent Signed-off-by: Linus Torvalds --- fs/autofs4/expire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index aa39ae83f01..3da18d45348 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c @@ -77,7 +77,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry) } /* Update the expiry counter if fs is busy */ - if (!may_umount_tree(mnt)) { + if (!may_umount_tree(path.mnt)) { struct autofs_info *ino = autofs4_dentry_ino(top); ino->last_used = jiffies; goto done; From f61f925859c57f6175082aeeee17743c68558a6e Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 5 Sep 2009 13:33:23 -0400 Subject: [PATCH 21/21] Revert "ACPI: Attach the ACPI device to the ACPI handle as early as possible" This reverts commit eab4b645769fa2f8703f5a3cb0cc4ac090d347af. http://bugzilla.kernel.org/show_bug.cgi?id=13002 Signed-off-by: Len Brown --- drivers/acpi/scan.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 781435d7e36..5dd702c9c1f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1263,16 +1263,6 @@ acpi_add_single_object(struct acpi_device **child, */ acpi_device_set_id(device, parent, handle, type); - /* - * The ACPI device is attached to acpi handle before getting - * the power/wakeup/peformance flags. Otherwise OS can't get - * the corresponding ACPI device by the acpi handle in the course - * of getting the power/wakeup/performance flags. - */ - result = acpi_device_set_context(device, type); - if (result) - goto end; - /* * Power Management * ---------------- @@ -1303,6 +1293,8 @@ acpi_add_single_object(struct acpi_device **child, goto end; } + if ((result = acpi_device_set_context(device, type))) + goto end; result = acpi_device_register(device, parent);